mirror of https://github.com/webpack/webpack.git
Merge branch 'main' into devtool-types
# Conflicts: # schemas/WebpackOptions.check.js
This commit is contained in:
commit
53f5d171f5
|
@ -3,4 +3,5 @@ test/statsCases/** eol=lf
|
|||
examples/* eol=lf
|
||||
bin/* eol=lf
|
||||
*.svg eol=lf
|
||||
*.css eol=lf
|
||||
**/*webpack.lock.data/** -text
|
||||
|
|
|
@ -21,8 +21,8 @@ jobs:
|
|||
- name: Use Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16.x
|
||||
cache: 'yarn'
|
||||
node-version: 17.x
|
||||
cache: "yarn"
|
||||
- run: yarn --frozen-lockfile
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
|
@ -37,8 +37,8 @@ jobs:
|
|||
- name: Use Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16.x
|
||||
cache: 'yarn'
|
||||
node-version: 17.x
|
||||
cache: "yarn"
|
||||
- run: yarn --frozen-lockfile
|
||||
- run: yarn link --frozen-lockfile || true
|
||||
- run: yarn link webpack --frozen-lockfile
|
||||
|
@ -54,8 +54,8 @@ jobs:
|
|||
- name: Use Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16.x
|
||||
cache: 'yarn'
|
||||
node-version: 17.x
|
||||
cache: "yarn"
|
||||
- run: yarn --frozen-lockfile
|
||||
- run: yarn link --frozen-lockfile || true
|
||||
- run: yarn link webpack --frozen-lockfile
|
||||
|
@ -75,9 +75,12 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
node-version: [10.x, 16.x]
|
||||
node-version: [10.x, 17.x]
|
||||
part: [a, b]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
node-version: 16.x
|
||||
part: a
|
||||
- os: ubuntu-latest
|
||||
node-version: 14.x
|
||||
part: a
|
||||
|
@ -91,7 +94,7 @@ jobs:
|
|||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'yarn'
|
||||
cache: "yarn"
|
||||
- run: yarn --frozen-lockfile
|
||||
- run: yarn link --frozen-lockfile || true
|
||||
- run: yarn link webpack --frozen-lockfile
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
/test/fixtures/temp-*
|
||||
/test/temp
|
||||
/test/ChangesAndRemovals
|
||||
/test/**/dev-defaults.webpack.lock
|
||||
/benchmark/js
|
||||
/benchmark/fixtures
|
||||
/examples/**/dist
|
||||
|
|
74
.travis.yml
74
.travis.yml
|
@ -1,74 +0,0 @@
|
|||
dist: trusty
|
||||
language: node_js
|
||||
|
||||
branches:
|
||||
only:
|
||||
- webpack-4
|
||||
- main
|
||||
- next
|
||||
- dev-1
|
||||
|
||||
cache:
|
||||
yarn: true
|
||||
directories:
|
||||
- ".jest-cache"
|
||||
- ".eslintcache"
|
||||
|
||||
stages:
|
||||
- basic
|
||||
- advanced
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
node_js: "12"
|
||||
env: NO_WATCH_TESTS=1 JEST="--maxWorkers=2 --cacheDirectory .jest-cache" JOB_PART=basic
|
||||
stage: basic
|
||||
- os: linux
|
||||
node_js: "12"
|
||||
env: NO_WATCH_TESTS=1 JEST="--maxWorkers=2 --cacheDirectory .jest-cache" JOB_PART=lintunit
|
||||
stage: advanced
|
||||
- os: linux
|
||||
node_js: "12"
|
||||
env: NO_WATCH_TESTS=1 JEST="--maxWorkers=2 --cacheDirectory .jest-cache" JOB_PART=integration
|
||||
stage: advanced
|
||||
- os: linux
|
||||
node_js: "12"
|
||||
env: NO_WATCH_TESTS=1 ALTERNATIVE_SORT=1 JEST="--maxWorkers=2 --cacheDirectory .jest-cache" JOB_PART=integration
|
||||
stage: advanced
|
||||
- os: linux
|
||||
node_js: "10"
|
||||
env:
|
||||
- NODEJS_VERSION=v15.0.0-nightly2020082003293aa3a1
|
||||
- YARN_EXTRA_ARGS="--ignore-engines"
|
||||
- NO_WATCH_TESTS=1
|
||||
- JEST="--maxWorkers=2 --cacheDirectory .jest-cache"
|
||||
- JOB_PART=integration
|
||||
stage: advanced
|
||||
fast_finish: true
|
||||
|
||||
before_install:
|
||||
- |
|
||||
if [ "$NODEJS_VERSION" != "" ];
|
||||
then
|
||||
mkdir /opt/node
|
||||
curl --silent "https://nodejs.org/download/nightly/$NODEJS_VERSION/node-$NODEJS_VERSION-linux-x64.tar.gz" | tar -zxf - --directory /opt/node
|
||||
export PATH="/opt/node/node-$NODEJS_VERSION-linux-x64/bin:$PATH"
|
||||
node --version
|
||||
fi
|
||||
|
||||
install:
|
||||
- yarn --frozen-lockfile $YARN_EXTRA_ARGS
|
||||
- yarn link --frozen-lockfile $YARN_EXTRA_ARGS || true
|
||||
- yarn link webpack --frozen-lockfile $YARN_EXTRA_ARGS
|
||||
|
||||
script: yarn travis:$JOB_PART
|
||||
|
||||
after_success:
|
||||
- cat ./coverage/lcov.info | node_modules/.bin/coveralls --verbose
|
||||
- bash <(curl -s https://codecov.io/bash) -F $JOB_PART -X gcov
|
||||
- rm -f .jest-cache/haste-map* .jest-cache/perf-cache*
|
||||
|
||||
notifications:
|
||||
slack:
|
||||
secure: JduSdKWwbnLCwo7Z4E59SGE+Uw832UwnXzQiKEpg1BV45MYDPRiGltly1tRHmPh9OGjvGx3XSkC2tNGOBLtL4UL2SCkf012x0t7jDutKRfcv/njynl8jk8l+UhPmaWiHXDQAgGiiKdL4RfzPLW3HeVHCOWm0LKMzcarTa8tw+rE=
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
[![node][node]][node-url]
|
||||
[![deps][deps]][deps-url]
|
||||
[![tests][tests]][tests-url]
|
||||
[![builds][builds]][builds-url]
|
||||
[![builds2][builds2]][builds2-url]
|
||||
[![coverage][cover]][cover-url]
|
||||
[![licenses][licenses]][licenses-url]
|
||||
|
@ -703,12 +701,8 @@ src="https://static.monei.net/monei-logo.svg" height="30" alt="MONEI"></a>
|
|||
[node-url]: https://nodejs.org
|
||||
[deps]: https://img.shields.io/david/webpack/webpack.svg
|
||||
[deps-url]: https://david-dm.org/webpack/webpack
|
||||
[tests]: https://img.shields.io/travis/webpack/webpack/main.svg
|
||||
[tests-url]: https://travis-ci.org/webpack/webpack
|
||||
[prs]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg
|
||||
[prs-url]: https://webpack.js.org/contribute/
|
||||
[builds-url]: https://ci.appveyor.com/project/sokra/webpack/branch/main
|
||||
[builds]: https://ci.appveyor.com/api/projects/status/github/webpack/webpack?svg=true
|
||||
[builds2]: https://dev.azure.com/webpack/webpack/_apis/build/status/webpack.webpack
|
||||
[builds2-url]: https://dev.azure.com/webpack/webpack/_build/latest?definitionId=3
|
||||
[licenses-url]: https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fwebpack%2Fwebpack?ref=badge_shield
|
||||
|
|
37
appveyor.yml
37
appveyor.yml
|
@ -1,37 +0,0 @@
|
|||
# appveyor file
|
||||
# http://www.appveyor.com/docs/appveyor-yml
|
||||
|
||||
branches:
|
||||
only:
|
||||
- webpack-4
|
||||
- main
|
||||
- next
|
||||
- dev-1
|
||||
|
||||
init:
|
||||
- git config --global core.autocrlf input
|
||||
|
||||
cache:
|
||||
- "..\\.yarn-cache"
|
||||
- ".jest-cache"
|
||||
|
||||
install:
|
||||
- ps: Install-Product node 14 x64
|
||||
- yarn --frozen-lockfile --preferred-cache-folder ..\\.yarn-cache
|
||||
- yarn link --frozen-lockfile --preferred-cache-folder ..\\.yarn-cache || yarn link --frozen-lockfile --preferred-cache-folder ..\\.yarn-cache
|
||||
- yarn link webpack --frozen-lockfile --preferred-cache-folder ..\\.yarn-cache
|
||||
|
||||
build: off
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
test_script:
|
||||
- node --version
|
||||
- yarn --version
|
||||
- cmd: set JEST=--maxWorkers=2 --cacheDirectory .jest-cache
|
||||
- cmd: yarn appveyor:integration
|
||||
- cmd: yarn cover:report --reporter=lcovonly
|
||||
- cmd: yarn unlink webpack
|
||||
- cmd: yarn global add codecov && codecov -F integration --disable=gcov
|
||||
- cmd: del /F /Q .jest-cache\\haste-map* .jest-cache\\perf-cache* 2> null || Ver > null
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
** ********************************************************************
|
||||
** md4.c -- Implementation of MD4 Message Digest Algorithm **
|
||||
** Updated: 2/16/90 by Ronald L. Rivest **
|
||||
** (C) 1990 RSA Data Security, Inc. **
|
||||
** ********************************************************************
|
||||
*/
|
||||
|
||||
// Ported to assemblyscript by Tobias Koppers
|
||||
|
||||
let totalLength: u32;
|
||||
let A: u32;
|
||||
let B: u32;
|
||||
let C: u32;
|
||||
let D: u32;
|
||||
|
||||
function F(x: u32, y: u32, z: u32): u32 {
|
||||
return z ^ (x & (y ^ z));
|
||||
}
|
||||
function G(x: u32, y: u32, z: u32): u32 {
|
||||
return (x & (y | z)) | (y & z);
|
||||
}
|
||||
function H(x: u32, y: u32, z: u32): u32 {
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
|
||||
function roundF(a: u32, b: u32, c: u32, d: u32, i: u32, s: u32): u32 {
|
||||
return rotl<u32>(a + F(b, c, d) + load<u32>(i), s);
|
||||
}
|
||||
function roundG(a: u32, b: u32, c: u32, d: u32, i: u32, s: u32): u32 {
|
||||
return rotl<u32>(a + G(b, c, d) + load<u32>(i) + 0x5a827999, s);
|
||||
}
|
||||
function roundH(a: u32, b: u32, c: u32, d: u32, i: u32, s: u32): u32 {
|
||||
return rotl<u32>(a + H(b, c, d) + load<u32>(i) + 0x6ed9eba1, s);
|
||||
}
|
||||
|
||||
export function init(): void {
|
||||
A = 0x67452301;
|
||||
B = 0xefcdab89;
|
||||
C = 0x98badcfe;
|
||||
D = 0x10325476;
|
||||
totalLength = 0;
|
||||
}
|
||||
|
||||
function body(size: u32): void {
|
||||
let _A = A;
|
||||
let _B = B;
|
||||
let _C = C;
|
||||
let _D = D;
|
||||
|
||||
for (let i: u32 = 0; i < size; i += 64) {
|
||||
let a = _A;
|
||||
let b = _B;
|
||||
let c = _C;
|
||||
let d = _D;
|
||||
|
||||
// Round F
|
||||
|
||||
a = roundF(a, b, c, d, i + 4 * 0, 3);
|
||||
d = roundF(d, a, b, c, i + 4 * 1, 7);
|
||||
c = roundF(c, d, a, b, i + 4 * 2, 11);
|
||||
b = roundF(b, c, d, a, i + 4 * 3, 19);
|
||||
|
||||
a = roundF(a, b, c, d, i + 4 * 4, 3);
|
||||
d = roundF(d, a, b, c, i + 4 * 5, 7);
|
||||
c = roundF(c, d, a, b, i + 4 * 6, 11);
|
||||
b = roundF(b, c, d, a, i + 4 * 7, 19);
|
||||
|
||||
a = roundF(a, b, c, d, i + 4 * 8, 3);
|
||||
d = roundF(d, a, b, c, i + 4 * 9, 7);
|
||||
c = roundF(c, d, a, b, i + 4 * 10, 11);
|
||||
b = roundF(b, c, d, a, i + 4 * 11, 19);
|
||||
|
||||
a = roundF(a, b, c, d, i + 4 * 12, 3);
|
||||
d = roundF(d, a, b, c, i + 4 * 13, 7);
|
||||
c = roundF(c, d, a, b, i + 4 * 14, 11);
|
||||
b = roundF(b, c, d, a, i + 4 * 15, 19);
|
||||
|
||||
// Round G
|
||||
|
||||
a = roundG(a, b, c, d, i + 4 * 0, 3);
|
||||
d = roundG(d, a, b, c, i + 4 * 4, 5);
|
||||
c = roundG(c, d, a, b, i + 4 * 8, 9);
|
||||
b = roundG(b, c, d, a, i + 4 * 12, 13);
|
||||
|
||||
a = roundG(a, b, c, d, i + 4 * 1, 3);
|
||||
d = roundG(d, a, b, c, i + 4 * 5, 5);
|
||||
c = roundG(c, d, a, b, i + 4 * 9, 9);
|
||||
b = roundG(b, c, d, a, i + 4 * 13, 13);
|
||||
|
||||
a = roundG(a, b, c, d, i + 4 * 2, 3);
|
||||
d = roundG(d, a, b, c, i + 4 * 6, 5);
|
||||
c = roundG(c, d, a, b, i + 4 * 10, 9);
|
||||
b = roundG(b, c, d, a, i + 4 * 14, 13);
|
||||
|
||||
a = roundG(a, b, c, d, i + 4 * 3, 3);
|
||||
d = roundG(d, a, b, c, i + 4 * 7, 5);
|
||||
c = roundG(c, d, a, b, i + 4 * 11, 9);
|
||||
b = roundG(b, c, d, a, i + 4 * 15, 13);
|
||||
|
||||
// Round H
|
||||
|
||||
a = roundH(a, b, c, d, i + 4 * 0, 3);
|
||||
d = roundH(d, a, b, c, i + 4 * 8, 9);
|
||||
c = roundH(c, d, a, b, i + 4 * 4, 11);
|
||||
b = roundH(b, c, d, a, i + 4 * 12, 15);
|
||||
|
||||
a = roundH(a, b, c, d, i + 4 * 2, 3);
|
||||
d = roundH(d, a, b, c, i + 4 * 10, 9);
|
||||
c = roundH(c, d, a, b, i + 4 * 6, 11);
|
||||
b = roundH(b, c, d, a, i + 4 * 14, 15);
|
||||
|
||||
a = roundH(a, b, c, d, i + 4 * 1, 3);
|
||||
d = roundH(d, a, b, c, i + 4 * 9, 9);
|
||||
c = roundH(c, d, a, b, i + 4 * 5, 11);
|
||||
b = roundH(b, c, d, a, i + 4 * 13, 15);
|
||||
|
||||
a = roundH(a, b, c, d, i + 4 * 3, 3);
|
||||
d = roundH(d, a, b, c, i + 4 * 11, 9);
|
||||
c = roundH(c, d, a, b, i + 4 * 7, 11);
|
||||
b = roundH(b, c, d, a, i + 4 * 15, 15);
|
||||
|
||||
_A += a;
|
||||
_B += b;
|
||||
_C += c;
|
||||
_D += d;
|
||||
}
|
||||
|
||||
A = _A;
|
||||
B = _B;
|
||||
C = _C;
|
||||
D = _D;
|
||||
}
|
||||
|
||||
export function update(length: u32): void {
|
||||
body(length);
|
||||
totalLength += length;
|
||||
}
|
||||
|
||||
export function final(length: u32): void {
|
||||
const bits: u64 = u64(totalLength + length) << 3;
|
||||
const finalLength: u32 = (length + 9 + 63) & ~63;
|
||||
const bitsPosition = finalLength - 8;
|
||||
|
||||
// end
|
||||
store<u8>(length++, 0x80);
|
||||
|
||||
// padding
|
||||
for (; length & 7 && length < finalLength; length++) store<u8>(length, 0);
|
||||
for (; length < finalLength; length += 8) store<u64>(length, 0);
|
||||
|
||||
// bits
|
||||
store<u64>(bitsPosition, bits);
|
||||
|
||||
body(finalLength);
|
||||
|
||||
store<u64>(0, u32ToHex(A));
|
||||
store<u64>(8, u32ToHex(B));
|
||||
store<u64>(16, u32ToHex(C));
|
||||
store<u64>(24, u32ToHex(D));
|
||||
}
|
||||
|
||||
function u32ToHex(x: u64): u64 {
|
||||
// from https://johnnylee-sde.github.io/Fast-unsigned-integer-to-hex-string/
|
||||
|
||||
x = ((x & 0xffff0000) << 16) | (x & 0xffff);
|
||||
x = ((x & 0x0000ff000000ff00) << 8) | (x & 0x000000ff000000ff);
|
||||
x = ((x & 0x00f000f000f000f0) >> 4) | ((x & 0x000f000f000f000f) << 8);
|
||||
|
||||
const mask = ((x + 0x0606060606060606) >> 4) & 0x0101010101010101;
|
||||
|
||||
x |= 0x3030303030303030;
|
||||
|
||||
x += 0x27 * mask;
|
||||
|
||||
return x;
|
||||
}
|
|
@ -108,8 +108,6 @@ export function final(length: u32): void {
|
|||
result *= Prime3;
|
||||
result ^= result >> 32;
|
||||
|
||||
store<u64>(0, result);
|
||||
|
||||
store<u64>(0, u32ToHex(result >> 32));
|
||||
store<u64>(8, u32ToHex(result & 0xffffffff));
|
||||
}
|
||||
|
|
|
@ -86,13 +86,7 @@ jobs:
|
|||
- script: |
|
||||
set -e
|
||||
export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH"
|
||||
yarn -s run code-lint --format junit > junit.xml
|
||||
yarn special-lint
|
||||
yarn type-lint
|
||||
yarn typings-lint
|
||||
yarn yarn-lint
|
||||
yarn pretty-lint
|
||||
yarn spellcheck
|
||||
yarn lint
|
||||
env:
|
||||
CI: "true"
|
||||
displayName: "Run linting"
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
const createHash = require("../lib/util/createHash");
|
||||
|
||||
const compare = require("./micro-compare");
|
||||
|
||||
const size = 50;
|
||||
|
||||
const strings = [];
|
||||
for (let count = 1; ; count *= 10) {
|
||||
while (strings.length < count) {
|
||||
const s = require("crypto").randomBytes(size).toString("hex");
|
||||
strings.push(s);
|
||||
const hash = createHash("native-md4");
|
||||
hash.update(s);
|
||||
hash.update(s);
|
||||
hash.digest("hex");
|
||||
}
|
||||
let i = 0;
|
||||
console.log(
|
||||
`${count} different 200 char strings: ` +
|
||||
compare(
|
||||
"native md4",
|
||||
() => {
|
||||
const hash = createHash("native-md4");
|
||||
const s = strings[(i = (i + 1) % strings.length)];
|
||||
hash.update(s);
|
||||
hash.update(s);
|
||||
return hash.digest("hex");
|
||||
},
|
||||
"wasm md4",
|
||||
() => {
|
||||
const hash = createHash("md4");
|
||||
const s = strings[(i = (i + 1) % strings.length)];
|
||||
hash.update(s);
|
||||
hash.update(s);
|
||||
return hash.digest("hex");
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
const createHash = require("../lib/util/createHash");
|
||||
|
||||
const compare = require("./micro-compare");
|
||||
|
||||
for (const size of [
|
||||
1, 10, 20, 40, 60, 80, 100, 200, 400, 1000, 1001, 5000, 8183, 8184, 8185,
|
||||
10000, 20000, 32768, 32769, 50000, 100000, 200000
|
||||
]) {
|
||||
const longString = require("crypto").randomBytes(size).toString("hex");
|
||||
const buffer = require("crypto").randomBytes(size * 2);
|
||||
console.log(
|
||||
`string ${longString.length} chars: ` +
|
||||
compare(
|
||||
"native md4",
|
||||
() => {
|
||||
const hash = createHash("native-md4");
|
||||
hash.update(longString);
|
||||
hash.update(longString);
|
||||
return hash.digest("hex");
|
||||
},
|
||||
"wasm md4",
|
||||
() => {
|
||||
const hash = createHash("md4");
|
||||
hash.update(longString);
|
||||
hash.update(longString);
|
||||
return hash.digest("hex");
|
||||
}
|
||||
)
|
||||
);
|
||||
console.log(
|
||||
`buffer ${buffer.length} bytes: ` +
|
||||
compare(
|
||||
"native md4",
|
||||
() => {
|
||||
const hash = createHash("native-md4");
|
||||
hash.update(buffer);
|
||||
hash.update(buffer);
|
||||
return hash.digest("hex");
|
||||
},
|
||||
"wasm md4",
|
||||
() => {
|
||||
const hash = createHash("md4");
|
||||
hash.update(buffer);
|
||||
hash.update(buffer);
|
||||
return hash.digest("hex");
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
let result;
|
||||
|
||||
const measure = (fn, count) => {
|
||||
const start = process.hrtime.bigint();
|
||||
for (let i = 0; i < count; i++) result = fn();
|
||||
return Number(process.hrtime.bigint() - start);
|
||||
};
|
||||
|
||||
const NS_PER_MS = 1000000; // 1ms
|
||||
const MIN_DURATION = 100 * NS_PER_MS; // 100ms
|
||||
const MAX_DURATION = 1000 * NS_PER_MS; // 1000ms
|
||||
const MAX_WARMUP_DURATION = 1 * NS_PER_MS; // 1ms
|
||||
|
||||
const format = (fast, slow, fastName, slowName, count) => {
|
||||
return `${fastName} is ${
|
||||
Math.round(((slow - fast) * 1000) / slow) / 10
|
||||
}% faster than ${slowName} (${Math.round(fast / 100 / count) / 10} µs vs ${
|
||||
Math.round(slow / 100 / count) / 10
|
||||
} µs, ${count}x)`;
|
||||
};
|
||||
|
||||
const compare = (n1, f1, n2, f2) => {
|
||||
let count = 1;
|
||||
while (true) {
|
||||
const timings = [f1, f2, f1, f2, f1, f2].map(f => measure(f, count));
|
||||
const t1 = Math.min(timings[0], timings[2], timings[4]);
|
||||
const t2 = Math.min(timings[1], timings[3], timings[5]);
|
||||
if (count === 1 && (t1 > MAX_WARMUP_DURATION || t2 > MAX_WARMUP_DURATION)) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
(t1 > MIN_DURATION && t2 > MIN_DURATION) ||
|
||||
t1 > MAX_DURATION ||
|
||||
t2 > MAX_DURATION
|
||||
) {
|
||||
return t1 > t2
|
||||
? format(t2, t1, n2, n1, count)
|
||||
: format(t1, t2, n1, n2, count);
|
||||
}
|
||||
count *= 2;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = compare;
|
|
@ -0,0 +1,45 @@
|
|||
const createHash = require("../lib/util/createHash");
|
||||
|
||||
const compare = require("./micro-compare");
|
||||
|
||||
for (const size of [
|
||||
1, 10, 20, 40, 60, 80, 100, 200, 400, 1000, 1001, 5000, 8183, 8184, 8185,
|
||||
10000, 20000, 32768, 32769, 50000, 100000, 200000
|
||||
]) {
|
||||
const longString = require("crypto").randomBytes(size).toString("hex");
|
||||
const buffer = require("crypto").randomBytes(size * 2);
|
||||
console.log(
|
||||
`string ${longString.length} chars: ` +
|
||||
compare(
|
||||
"wasm xxhash64",
|
||||
() => {
|
||||
const hash = createHash("xxhash64");
|
||||
hash.update(longString);
|
||||
return hash.digest("hex");
|
||||
},
|
||||
"wasm md4",
|
||||
() => {
|
||||
const hash = createHash("md4");
|
||||
hash.update(longString);
|
||||
return hash.digest("hex");
|
||||
}
|
||||
)
|
||||
);
|
||||
console.log(
|
||||
`buffer ${buffer.length} bytes: ` +
|
||||
compare(
|
||||
"wasm xxhash64",
|
||||
() => {
|
||||
const hash = createHash("xxhash64");
|
||||
hash.update(buffer);
|
||||
return hash.digest("hex");
|
||||
},
|
||||
"wasm md4",
|
||||
() => {
|
||||
const hash = createHash("md4");
|
||||
hash.update(buffer);
|
||||
return hash.digest("hex");
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
const createHash = require("../lib/util/createHash");
|
||||
|
||||
const compare = require("./micro-compare");
|
||||
|
||||
for (const size of [
|
||||
1, 10, 20, 40, 60, 80, 100, 200, 400, 1000, 1001, 5000, 8183, 8184, 8185,
|
||||
10000, 20000, 32768, 32769, 50000, 100000, 200000
|
||||
]) {
|
||||
const longString = require("crypto").randomBytes(size).toString("hex");
|
||||
const buffer = require("crypto").randomBytes(size * 2);
|
||||
console.log(
|
||||
`string ${longString.length} chars: ` +
|
||||
compare(
|
||||
"wasm xxhash64",
|
||||
() => {
|
||||
const hash = createHash("xxhash64");
|
||||
hash.update(longString);
|
||||
hash.update(longString);
|
||||
return hash.digest("hex");
|
||||
},
|
||||
"native md4",
|
||||
() => {
|
||||
const hash = createHash("native-md4");
|
||||
hash.update(longString);
|
||||
hash.update(longString);
|
||||
return hash.digest("hex");
|
||||
}
|
||||
)
|
||||
);
|
||||
console.log(
|
||||
`buffer ${buffer.length} bytes: ` +
|
||||
compare(
|
||||
"wasm xxhash64",
|
||||
() => {
|
||||
const hash = createHash("xxhash64");
|
||||
hash.update(buffer);
|
||||
hash.update(buffer);
|
||||
return hash.digest("hex");
|
||||
},
|
||||
"native md4",
|
||||
() => {
|
||||
const hash = createHash("native-md4");
|
||||
hash.update(buffer);
|
||||
hash.update(buffer);
|
||||
return hash.digest("hex");
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
497
cspell.json
497
cspell.json
|
@ -1,241 +1,308 @@
|
|||
{
|
||||
"version": "0.1",
|
||||
"version": "0.2",
|
||||
"language": "en",
|
||||
"words": [
|
||||
"webpack",
|
||||
"webpack's",
|
||||
"endregion",
|
||||
"entrypoint",
|
||||
"entrypoints",
|
||||
"splitted",
|
||||
"dedupe",
|
||||
"deduplication",
|
||||
"deduplicating",
|
||||
"unoptimized",
|
||||
"prefetch",
|
||||
"prefetching",
|
||||
"prefetched",
|
||||
"preload",
|
||||
"preloading",
|
||||
"preloaded",
|
||||
"gzipping",
|
||||
"brotli",
|
||||
"submodule",
|
||||
"submodules",
|
||||
"typeof",
|
||||
"devtool",
|
||||
"wasi",
|
||||
"wasm",
|
||||
"webassembly",
|
||||
"IIFE",
|
||||
"IIFE's",
|
||||
"bigint",
|
||||
"unexception",
|
||||
"etag",
|
||||
"builtins",
|
||||
"uncacheable",
|
||||
"cacheable",
|
||||
"mergeable",
|
||||
"devtools",
|
||||
"transpiled",
|
||||
"mixins",
|
||||
"subdir",
|
||||
"errored",
|
||||
"eval",
|
||||
"multiplicator",
|
||||
"finalizer",
|
||||
"promisify",
|
||||
"absolutify",
|
||||
"camelcase",
|
||||
"filebase",
|
||||
"moduleid",
|
||||
"modulehash",
|
||||
"chunkfilename",
|
||||
"chunkname",
|
||||
"chunkhash",
|
||||
"fullhash",
|
||||
"contenthash",
|
||||
"hashable",
|
||||
"hotupdatechunk",
|
||||
"middleware",
|
||||
"middlewares",
|
||||
"serializer",
|
||||
"serializers",
|
||||
"deserialization",
|
||||
"referenceable",
|
||||
"polyfilled",
|
||||
"transpiling",
|
||||
"transpile",
|
||||
"transpiles",
|
||||
"snapshotting",
|
||||
"sourcemap",
|
||||
"nosources",
|
||||
"filepath",
|
||||
"subpath",
|
||||
"pathinfo",
|
||||
"undelayed",
|
||||
"microtask",
|
||||
"microtasks",
|
||||
"deopt",
|
||||
"deopts",
|
||||
"sandboxed",
|
||||
"mangleable",
|
||||
"passthrough",
|
||||
"prioritise",
|
||||
"booleanized",
|
||||
"serializables",
|
||||
"unreviewed",
|
||||
"unshifted",
|
||||
"nonrecursive",
|
||||
"symlinked",
|
||||
"subfolder",
|
||||
"prettierrc",
|
||||
"templated",
|
||||
"templating",
|
||||
"kibibytes",
|
||||
"mebibytes",
|
||||
"gibibytes",
|
||||
"typechecker",
|
||||
"recurse",
|
||||
"preparsed",
|
||||
"acircular",
|
||||
"amdmodule",
|
||||
"asmjs",
|
||||
"assemblyscript",
|
||||
"asyncloader",
|
||||
"atlaskit",
|
||||
"autocrlf",
|
||||
"lcov",
|
||||
"lcovonly",
|
||||
"gcov",
|
||||
"lintunit",
|
||||
"instanceof",
|
||||
"loglevel",
|
||||
"runtime",
|
||||
"runtimes",
|
||||
"mimetype",
|
||||
"testvalue",
|
||||
"unusedkey",
|
||||
"unusedvalue",
|
||||
"performant",
|
||||
"watchings",
|
||||
"jsons",
|
||||
"exitance",
|
||||
"ident",
|
||||
"idents",
|
||||
"globstar",
|
||||
"inversed",
|
||||
"concated",
|
||||
"RBDT",
|
||||
"opensource",
|
||||
"babeljs",
|
||||
"backport",
|
||||
"backported",
|
||||
"basictest",
|
||||
"bigint",
|
||||
"Biró",
|
||||
"bitfield",
|
||||
"bomfile",
|
||||
"booleanized",
|
||||
"boolish",
|
||||
"brotli",
|
||||
"browserified",
|
||||
"browserslist",
|
||||
"browserslistrc",
|
||||
"Brumme",
|
||||
"bugfix",
|
||||
"bugfixes",
|
||||
"declarators",
|
||||
"rrrlll",
|
||||
"undefine",
|
||||
"finializer",
|
||||
"quasis",
|
||||
"hashs",
|
||||
"functype",
|
||||
"funcindex",
|
||||
"Descr",
|
||||
"valtype",
|
||||
"informations",
|
||||
"reexecuted",
|
||||
"global's",
|
||||
"unsplittable",
|
||||
"builtins",
|
||||
"cacheable",
|
||||
"callme",
|
||||
"camelcase",
|
||||
"chainable",
|
||||
"metacharacters",
|
||||
"Xarray",
|
||||
"Xfactory",
|
||||
"Xmodule",
|
||||
"Xexports",
|
||||
"moji",
|
||||
"bitfield",
|
||||
"precompute",
|
||||
"toplevel",
|
||||
"modulos",
|
||||
"untaint",
|
||||
"ufeff",
|
||||
"timestamping",
|
||||
"loadername",
|
||||
"laof",
|
||||
"chunkfilename",
|
||||
"chunkhash",
|
||||
"chunkname",
|
||||
"cmodule",
|
||||
"codecov",
|
||||
"cofounder",
|
||||
"hashchange",
|
||||
"popstate",
|
||||
"hotpink",
|
||||
"navigations",
|
||||
"Collet's",
|
||||
"compat",
|
||||
"noimport",
|
||||
"tmpl",
|
||||
"concated",
|
||||
"contenthash",
|
||||
"contextifies",
|
||||
"crossorigin",
|
||||
"csvg",
|
||||
"repo",
|
||||
"repos",
|
||||
"triaging",
|
||||
"valign",
|
||||
"returnfalse",
|
||||
"return'development",
|
||||
"datastructures",
|
||||
"prewalking",
|
||||
"overridables",
|
||||
"overridable",
|
||||
"cujojs",
|
||||
"Dani",
|
||||
"darkblue",
|
||||
"darkgreen",
|
||||
"darkred",
|
||||
"eqeqeq",
|
||||
"boolish",
|
||||
"analysing",
|
||||
"etags",
|
||||
"datastructures",
|
||||
"declarators",
|
||||
"dedupe",
|
||||
"deduplicating",
|
||||
"deduplication",
|
||||
"defunctzombie",
|
||||
"deopt",
|
||||
"deopts",
|
||||
"dependabot",
|
||||
"Descr",
|
||||
"deserialization",
|
||||
"destructure",
|
||||
"onconnect",
|
||||
"nwjs",
|
||||
"redeclaration",
|
||||
"kaios",
|
||||
"parallelism",
|
||||
"gitattributes",
|
||||
"hashbang",
|
||||
|
||||
"webassemblyjs",
|
||||
"assemblyscript",
|
||||
"fsevents",
|
||||
"watchpack",
|
||||
"tapable",
|
||||
"junit",
|
||||
"memfs",
|
||||
"rimraf",
|
||||
"devtool",
|
||||
"devtools",
|
||||
"donotcallme",
|
||||
"endregion",
|
||||
"entrypoint",
|
||||
"entrypoints",
|
||||
"Eoksni",
|
||||
"eqeqeq",
|
||||
"errored",
|
||||
"esmodule",
|
||||
"estree",
|
||||
"posthtml",
|
||||
"etag",
|
||||
"etags",
|
||||
"eval",
|
||||
"Ewald",
|
||||
"exitance",
|
||||
"filebase",
|
||||
"fileoverview",
|
||||
"filepath",
|
||||
"finalizer",
|
||||
"finializer",
|
||||
"fsevents",
|
||||
"fullhash",
|
||||
"funcindex",
|
||||
"functype",
|
||||
"gcov",
|
||||
"gibibytes",
|
||||
"gitattributes",
|
||||
"gitter",
|
||||
"global's",
|
||||
"globstar",
|
||||
"gzipping",
|
||||
"hashable",
|
||||
"hashbang",
|
||||
"hashchange",
|
||||
"hashs",
|
||||
"hotpink",
|
||||
"hotupdatechunk",
|
||||
"ident",
|
||||
"idents",
|
||||
"IIFE's",
|
||||
"IIFE",
|
||||
"informations",
|
||||
"instanceof",
|
||||
"inversed",
|
||||
"jhnns",
|
||||
"jrburke",
|
||||
"jsfile",
|
||||
"jsons",
|
||||
"junit",
|
||||
"Junya",
|
||||
"kaios",
|
||||
"Kees",
|
||||
"kibibytes",
|
||||
"Kluskens",
|
||||
"Koppers",
|
||||
"laof",
|
||||
"Larkin",
|
||||
"lcov",
|
||||
"lcovonly",
|
||||
"lintunit",
|
||||
"loadername",
|
||||
"loglevel",
|
||||
"longnameforexport",
|
||||
"mangleable",
|
||||
"MCEP",
|
||||
"mebibytes",
|
||||
"medikoo",
|
||||
"membertest",
|
||||
"memfs",
|
||||
"mergeable",
|
||||
"metacharacters",
|
||||
"microtask",
|
||||
"microtasks",
|
||||
"middleware",
|
||||
"middlewares",
|
||||
"mimetype",
|
||||
"mixins",
|
||||
"modulehash",
|
||||
"moduleid",
|
||||
"modulos",
|
||||
"moji",
|
||||
"MONEI",
|
||||
"mult",
|
||||
"multiplicator",
|
||||
"mylibrary",
|
||||
"mynamespace",
|
||||
"navigations",
|
||||
"nmodule",
|
||||
"noimport",
|
||||
"nonexistentfile",
|
||||
"nonrecursive",
|
||||
"nosource",
|
||||
"nosources",
|
||||
"nwjs",
|
||||
"onconnect",
|
||||
"opencollective",
|
||||
"opensource",
|
||||
"opuuus",
|
||||
"overridable",
|
||||
"overridables",
|
||||
"parallelism",
|
||||
"passthrough",
|
||||
"pathinfo",
|
||||
"performant",
|
||||
"Phoscur",
|
||||
"pmodule",
|
||||
"pnpm",
|
||||
"polyfilled",
|
||||
"popstate",
|
||||
"posthtml",
|
||||
"precompute",
|
||||
"prefetch",
|
||||
"prefetched",
|
||||
"prefetching",
|
||||
"preload",
|
||||
"preloaded",
|
||||
"preloading",
|
||||
"preparsed",
|
||||
"prettierrc",
|
||||
"prewalking",
|
||||
"prioritise",
|
||||
"promisify",
|
||||
"quasis",
|
||||
"queryloader",
|
||||
"querystrings",
|
||||
"RBDT",
|
||||
"recurse",
|
||||
"redeclaration",
|
||||
"reexecuted",
|
||||
"referenceable",
|
||||
"referencer",
|
||||
"repo",
|
||||
"repos",
|
||||
"return'development",
|
||||
"returnfalse",
|
||||
"revparse",
|
||||
"rimraf",
|
||||
"Rivest",
|
||||
"rrrlll",
|
||||
"runtime",
|
||||
"runtimes",
|
||||
"samsunginternet",
|
||||
"sandboxed",
|
||||
"serializables",
|
||||
"serializer",
|
||||
"serializers",
|
||||
"shama",
|
||||
"skypack",
|
||||
"snapshotting",
|
||||
"sokra",
|
||||
"somepackage",
|
||||
"somepath",
|
||||
"sourcemap",
|
||||
"sourcemapped",
|
||||
"splitted",
|
||||
"stylesheet",
|
||||
"subdir",
|
||||
"subfolder",
|
||||
"submodule",
|
||||
"submodules",
|
||||
"subpath",
|
||||
"substack",
|
||||
"symlinked",
|
||||
"syncloader",
|
||||
"systemjs",
|
||||
"tapable",
|
||||
"templated",
|
||||
"templating",
|
||||
"testcase",
|
||||
"testlink",
|
||||
"testloader",
|
||||
"testvalue",
|
||||
"timestamping",
|
||||
"tmpl",
|
||||
"toplevel",
|
||||
"traceur",
|
||||
"atlaskit",
|
||||
"transpile",
|
||||
"transpiled",
|
||||
"transpiles",
|
||||
"transpiling",
|
||||
"triaging",
|
||||
"Tshs",
|
||||
"typechecker",
|
||||
"typeof",
|
||||
"ufeff",
|
||||
"uncacheable",
|
||||
"undefine",
|
||||
"undelayed",
|
||||
"unexception",
|
||||
"unoptimized",
|
||||
"unreviewed",
|
||||
"unshifted",
|
||||
"unsplittable",
|
||||
"untaint",
|
||||
"unusedkey",
|
||||
"unusedvalue",
|
||||
"url's",
|
||||
"valign",
|
||||
"valtype",
|
||||
"wasi",
|
||||
"wasm",
|
||||
"watchings",
|
||||
"watchpack",
|
||||
"webassembly",
|
||||
"webassemblyjs",
|
||||
"webmake",
|
||||
"webpack's",
|
||||
"webpack",
|
||||
"Xarray",
|
||||
"Xexports",
|
||||
"Xfactory",
|
||||
"Xmodule",
|
||||
"xxhash",
|
||||
"xxhashjs",
|
||||
"systemjs",
|
||||
"skypack",
|
||||
|
||||
"sokra",
|
||||
"Koppers",
|
||||
"Junya",
|
||||
"Eoksni",
|
||||
"Ewald",
|
||||
"Larkin",
|
||||
"Kees",
|
||||
"Kluskens",
|
||||
"Phoscur",
|
||||
"defunctzombie",
|
||||
"shama",
|
||||
"jhnns",
|
||||
"substack",
|
||||
"MONEI",
|
||||
"medikoo",
|
||||
"webmake",
|
||||
"jrburke",
|
||||
"gitter",
|
||||
"codecov",
|
||||
"opencollective",
|
||||
"dependabot",
|
||||
"browserslist",
|
||||
"samsunginternet",
|
||||
"pnpm"
|
||||
"Yann"
|
||||
],
|
||||
"ignoreRegExpList": [
|
||||
"/Author.+/",
|
||||
"/data:.*/",
|
||||
"/\"mappings\":\".+\"/",
|
||||
"/toMatchInlineSnapshot\\(\\s*`[^`]*`\\s*\\)/"
|
||||
],
|
||||
"ignoreRegExpList": ["/Author.+/", "/data:.*/", "/\"mappings\":\".+\"/"],
|
||||
"ignorePaths": [
|
||||
"**/dist/**",
|
||||
"examples/**/README.md",
|
||||
"**/webpack.lock.data/**"
|
||||
"**/webpack.lock.data/**",
|
||||
"package.json",
|
||||
"yarn.lock",
|
||||
"types.d.ts",
|
||||
"**/**/*.snap",
|
||||
"test/cases/json/weird-properties/globals.json",
|
||||
"**/*.svg",
|
||||
"*.log",
|
||||
"**/*.wasm",
|
||||
"coverage/**",
|
||||
"test/**/module.js",
|
||||
"test/js/**",
|
||||
"test/cases/**",
|
||||
"test/configCases/**",
|
||||
"test/statsCases/**",
|
||||
"test/fixtures/**"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -204,7 +204,7 @@ declare module "@webassemblyjs/ast" {
|
|||
raw?: string
|
||||
): FloatLiteral;
|
||||
export function global(globalType: string, nodes: Node[]): Global;
|
||||
export function identifier(indentifier: string): Identifier;
|
||||
export function identifier(identifier: string): Identifier;
|
||||
export function funcParam(valType: string, id: Identifier): FuncParam;
|
||||
export function instruction(inst: string, args?: Node[]): Instruction;
|
||||
export function callInstruction(funcIndex: Index): CallInstruction;
|
||||
|
|
|
@ -5,6 +5,7 @@ import type { ResolveOptionsWithDependencyType } from "../lib/ResolverFactory";
|
|||
import type Compilation from "../lib/Compilation";
|
||||
import type Compiler from "../lib/Compiler";
|
||||
import type NormalModule from "../lib/NormalModule";
|
||||
import type Hash from "../lib/util/Hash";
|
||||
import type { InputFileSystem } from "../lib/util/fs";
|
||||
import type { Logger } from "../lib/logging/Logger";
|
||||
import type {
|
||||
|
@ -39,6 +40,7 @@ export interface NormalModuleLoaderContext<OptionsType> {
|
|||
utils: {
|
||||
absolutify: (context: string, request: string) => string;
|
||||
contextify: (context: string, request: string) => string;
|
||||
createHash: (algorithm?: string) => Hash;
|
||||
};
|
||||
rootContext: string;
|
||||
fs: InputFileSystem;
|
||||
|
|
|
@ -124,7 +124,7 @@ export type LibraryExport = string[] | string;
|
|||
*/
|
||||
export type LibraryName = string[] | string | LibraryCustomUmdObject;
|
||||
/**
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
*/
|
||||
export type LibraryType =
|
||||
| (
|
||||
|
@ -139,6 +139,7 @@ export type LibraryType =
|
|||
| "commonjs"
|
||||
| "commonjs2"
|
||||
| "commonjs-module"
|
||||
| "commonjs-static"
|
||||
| "amd"
|
||||
| "amd-require"
|
||||
| "umd"
|
||||
|
@ -182,6 +183,10 @@ export type WasmLoadingType =
|
|||
* An entry point without name.
|
||||
*/
|
||||
export type EntryUnnamed = EntryItem;
|
||||
/**
|
||||
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
|
||||
*/
|
||||
export type Experiments = ExperimentsCommon & ExperimentsExtra;
|
||||
/**
|
||||
* Specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on `output.libraryTarget`.
|
||||
*/
|
||||
|
@ -214,6 +219,7 @@ export type ExternalsType =
|
|||
| "commonjs"
|
||||
| "commonjs2"
|
||||
| "commonjs-module"
|
||||
| "commonjs-static"
|
||||
| "amd"
|
||||
| "amd-require"
|
||||
| "umd"
|
||||
|
@ -468,6 +474,14 @@ export type CompareBeforeEmit = boolean;
|
|||
* This option enables cross-origin loading of chunks.
|
||||
*/
|
||||
export type CrossOriginLoading = false | "anonymous" | "use-credentials";
|
||||
/**
|
||||
* Specifies the filename template of non-initial output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.
|
||||
*/
|
||||
export type CssChunkFilename = FilenameTemplate;
|
||||
/**
|
||||
* Specifies the filename template of output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.
|
||||
*/
|
||||
export type CssFilename = FilenameTemplate;
|
||||
/**
|
||||
* Similar to `output.devtoolModuleFilenameTemplate`, but used in the case of duplicate module identifiers.
|
||||
*/
|
||||
|
@ -707,6 +721,15 @@ export type AssetGeneratorDataUrlFunction = (
|
|||
*/
|
||||
export type AssetGeneratorOptions = AssetInlineGeneratorOptions &
|
||||
AssetResourceGeneratorOptions;
|
||||
/**
|
||||
* Emit the asset in the specified folder relative to 'output.path'. This should only be needed when custom 'publicPath' is specified to match the folder structure there.
|
||||
*/
|
||||
export type AssetModuleOutputPath =
|
||||
| string
|
||||
| ((
|
||||
pathData: import("../lib/Compilation").PathData,
|
||||
assetInfo?: import("../lib/Compilation").AssetInfo
|
||||
) => string);
|
||||
/**
|
||||
* Function that executes for module and should return whenever asset should be inlined as DataUrl.
|
||||
*/
|
||||
|
@ -722,6 +745,11 @@ export type EntryDynamicNormalized = () => Promise<EntryStaticNormalized>;
|
|||
* The entry point(s) of the compilation.
|
||||
*/
|
||||
export type EntryNormalized = EntryDynamicNormalized | EntryStaticNormalized;
|
||||
/**
|
||||
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
|
||||
*/
|
||||
export type ExperimentsNormalized = ExperimentsCommon &
|
||||
ExperimentsNormalizedExtra;
|
||||
/**
|
||||
* The dependency used for the external.
|
||||
*/
|
||||
|
@ -732,6 +760,18 @@ export type ExternalItemValue =
|
|||
| {
|
||||
[k: string]: any;
|
||||
};
|
||||
/**
|
||||
* List of allowed URIs for building http resources.
|
||||
*/
|
||||
export type HttpUriAllowedUris = HttpUriOptionsAllowedUris;
|
||||
/**
|
||||
* List of allowed URIs (resp. the beginning of them).
|
||||
*/
|
||||
export type HttpUriOptionsAllowedUris = (
|
||||
| RegExp
|
||||
| string
|
||||
| ((uri: string) => boolean)
|
||||
)[];
|
||||
/**
|
||||
* Ignore specific warnings.
|
||||
*/
|
||||
|
@ -970,11 +1010,11 @@ export interface FileCacheOptions {
|
|||
/**
|
||||
* List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.
|
||||
*/
|
||||
immutablePaths?: string[];
|
||||
immutablePaths?: (RegExp | string)[];
|
||||
/**
|
||||
* List of paths that are managed by a package manager and can be trusted to not be modified otherwise.
|
||||
*/
|
||||
managedPaths?: string[];
|
||||
managedPaths?: (RegExp | string)[];
|
||||
/**
|
||||
* Time for which unused cache entries stay in the filesystem cache at minimum (in milliseconds).
|
||||
*/
|
||||
|
@ -1027,6 +1067,10 @@ export interface EntryObject {
|
|||
* An object with entry point description.
|
||||
*/
|
||||
export interface EntryDescription {
|
||||
/**
|
||||
* Enable/disable creating async chunks that are loaded on demand.
|
||||
*/
|
||||
asyncChunks?: boolean;
|
||||
/**
|
||||
* The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).
|
||||
*/
|
||||
|
@ -1081,7 +1125,7 @@ export interface LibraryOptions {
|
|||
*/
|
||||
name?: LibraryName;
|
||||
/**
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
*/
|
||||
type: LibraryType;
|
||||
/**
|
||||
|
@ -1127,104 +1171,6 @@ export interface LibraryCustomUmdObject {
|
|||
*/
|
||||
root?: string[] | string;
|
||||
}
|
||||
/**
|
||||
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
|
||||
*/
|
||||
export interface Experiments {
|
||||
/**
|
||||
* Allow module type 'asset' to generate assets.
|
||||
*/
|
||||
asset?: boolean;
|
||||
/**
|
||||
* Support WebAssembly as asynchronous EcmaScript Module.
|
||||
*/
|
||||
asyncWebAssembly?: boolean;
|
||||
/**
|
||||
* Build http(s): urls using a lockfile and resource content cache.
|
||||
*/
|
||||
buildHttp?: boolean | HttpUriOptions;
|
||||
/**
|
||||
* Enable additional in memory caching of modules that are unchanged and reference only unchanged modules.
|
||||
*/
|
||||
cacheUnaffected?: boolean;
|
||||
/**
|
||||
* Apply defaults of next major version.
|
||||
*/
|
||||
futureDefaults?: boolean;
|
||||
/**
|
||||
* Enable module and chunk layers.
|
||||
*/
|
||||
layers?: boolean;
|
||||
/**
|
||||
* Compile entrypoints and import()s only when they are accessed.
|
||||
*/
|
||||
lazyCompilation?:
|
||||
| boolean
|
||||
| {
|
||||
/**
|
||||
* A custom backend.
|
||||
*/
|
||||
backend?:
|
||||
| ((
|
||||
compiler: import("../lib/Compiler"),
|
||||
client: string,
|
||||
callback: (err?: Error, api?: any) => void
|
||||
) => void)
|
||||
| ((
|
||||
compiler: import("../lib/Compiler"),
|
||||
client: string
|
||||
) => Promise<any>);
|
||||
/**
|
||||
* A custom client.
|
||||
*/
|
||||
client?: string;
|
||||
/**
|
||||
* Enable/disable lazy compilation for entries.
|
||||
*/
|
||||
entries?: boolean;
|
||||
/**
|
||||
* Enable/disable lazy compilation for import() modules.
|
||||
*/
|
||||
imports?: boolean;
|
||||
/**
|
||||
* Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name.
|
||||
*/
|
||||
test?: RegExp | string | ((module: import("../lib/Module")) => boolean);
|
||||
};
|
||||
/**
|
||||
* Allow output javascript files as module source type.
|
||||
*/
|
||||
outputModule?: boolean;
|
||||
/**
|
||||
* Support WebAssembly as synchronous EcmaScript Module (outdated).
|
||||
*/
|
||||
syncWebAssembly?: boolean;
|
||||
/**
|
||||
* Allow using top-level-await in EcmaScript Modules.
|
||||
*/
|
||||
topLevelAwait?: boolean;
|
||||
}
|
||||
/**
|
||||
* Options for building http resources.
|
||||
*/
|
||||
export interface HttpUriOptions {
|
||||
/**
|
||||
* Location where resource content is stored for lockfile entries. It's also possible to disable storing by passing false.
|
||||
*/
|
||||
cacheLocation?: false | string;
|
||||
/**
|
||||
* When set, anything that would lead to a modification of the lockfile or any resource content, will result in an error.
|
||||
*/
|
||||
frozen?: boolean;
|
||||
/**
|
||||
* Location of the lockfile.
|
||||
*/
|
||||
lockfileLocation?: string;
|
||||
/**
|
||||
* When set, resources of existing lockfile entries will be fetched and entries will be upgraded when resource content has changed.
|
||||
*/
|
||||
upgrade?: boolean;
|
||||
}
|
||||
/**
|
||||
* Enable presets of externals for specific targets.
|
||||
*/
|
||||
|
@ -1841,6 +1787,12 @@ export interface OptimizationSplitChunksOptions {
|
|||
* Sets the name delimiter for created chunks.
|
||||
*/
|
||||
automaticNameDelimiter?: string;
|
||||
/**
|
||||
* Select chunks for determining shared modules (defaults to "async", "initial" and "all" requires adding these chunks to the HTML).
|
||||
*/
|
||||
chunks?:
|
||||
| ("initial" | "async" | "all")
|
||||
| ((chunk: import("../lib/Chunk")) => boolean);
|
||||
/**
|
||||
* Maximal size hint for the on-demand chunks.
|
||||
*/
|
||||
|
@ -1857,6 +1809,10 @@ export interface OptimizationSplitChunksOptions {
|
|||
* Minimal size for the created chunk.
|
||||
*/
|
||||
minSize?: OptimizationSplitChunksSizes;
|
||||
/**
|
||||
* Minimum size reduction due to the created chunk.
|
||||
*/
|
||||
minSizeReduction?: OptimizationSplitChunksSizes;
|
||||
};
|
||||
/**
|
||||
* Sets the template for the filename for created chunks.
|
||||
|
@ -1903,6 +1859,10 @@ export interface OptimizationSplitChunksOptions {
|
|||
* Minimal size for the created chunks.
|
||||
*/
|
||||
minSize?: OptimizationSplitChunksSizes;
|
||||
/**
|
||||
* Minimum size reduction due to the created chunk.
|
||||
*/
|
||||
minSizeReduction?: OptimizationSplitChunksSizes;
|
||||
/**
|
||||
* Give chunks created a name (chunks with equal name are merged).
|
||||
*/
|
||||
|
@ -1983,6 +1943,10 @@ export interface OptimizationSplitChunksCacheGroup {
|
|||
* Minimal size for the created chunk.
|
||||
*/
|
||||
minSize?: OptimizationSplitChunksSizes;
|
||||
/**
|
||||
* Minimum size reduction due to the created chunk.
|
||||
*/
|
||||
minSizeReduction?: OptimizationSplitChunksSizes;
|
||||
/**
|
||||
* Give chunks for this cache group a name (chunks with equal name are merged).
|
||||
*/
|
||||
|
@ -2016,6 +1980,10 @@ export interface Output {
|
|||
* The filename of asset modules as relative path inside the 'output.path' directory.
|
||||
*/
|
||||
assetModuleFilename?: AssetModuleFilename;
|
||||
/**
|
||||
* Enable/disable creating async chunks that are loaded on demand.
|
||||
*/
|
||||
asyncChunks?: boolean;
|
||||
/**
|
||||
* Add a comment in the UMD wrapper.
|
||||
*/
|
||||
|
@ -2056,6 +2024,14 @@ export interface Output {
|
|||
* This option enables cross-origin loading of chunks.
|
||||
*/
|
||||
crossOriginLoading?: CrossOriginLoading;
|
||||
/**
|
||||
* Specifies the filename template of non-initial output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.
|
||||
*/
|
||||
cssChunkFilename?: CssChunkFilename;
|
||||
/**
|
||||
* Specifies the filename template of output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.
|
||||
*/
|
||||
cssFilename?: CssFilename;
|
||||
/**
|
||||
* Similar to `output.devtoolModuleFilenameTemplate`, but used in the case of duplicate module identifiers.
|
||||
*/
|
||||
|
@ -2141,7 +2117,7 @@ export interface Output {
|
|||
*/
|
||||
libraryExport?: LibraryExport;
|
||||
/**
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
*/
|
||||
libraryTarget?: LibraryType;
|
||||
/**
|
||||
|
@ -2254,6 +2230,14 @@ export interface Environment {
|
|||
* The environment supports EcmaScript Module syntax to import EcmaScript modules (import ... from '...').
|
||||
*/
|
||||
module?: boolean;
|
||||
/**
|
||||
* The environment supports optional chaining ('obj?.a' or 'obj?.()').
|
||||
*/
|
||||
optionalChaining?: boolean;
|
||||
/**
|
||||
* The environment supports template literals.
|
||||
*/
|
||||
templateLiteral?: boolean;
|
||||
}
|
||||
/**
|
||||
* Use a Trusted Types policy to create urls for chunks.
|
||||
|
@ -2305,11 +2289,11 @@ export interface SnapshotOptions {
|
|||
/**
|
||||
* List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.
|
||||
*/
|
||||
immutablePaths?: string[];
|
||||
immutablePaths?: (RegExp | string)[];
|
||||
/**
|
||||
* List of paths that are managed by a package manager and can be trusted to not be modified otherwise.
|
||||
*/
|
||||
managedPaths?: string[];
|
||||
managedPaths?: (RegExp | string)[];
|
||||
/**
|
||||
* Options for snapshotting dependencies of modules to determine if they need to be built again.
|
||||
*/
|
||||
|
@ -2759,11 +2743,23 @@ export interface AssetResourceGeneratorOptions {
|
|||
* Specifies the filename template of output files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.
|
||||
*/
|
||||
filename?: FilenameTemplate;
|
||||
/**
|
||||
* Emit the asset in the specified folder relative to 'output.path'. This should only be needed when custom 'publicPath' is specified to match the folder structure there.
|
||||
*/
|
||||
outputPath?: AssetModuleOutputPath;
|
||||
/**
|
||||
* The 'publicPath' specifies the public URL address of the output files when referenced in a browser.
|
||||
*/
|
||||
publicPath?: RawPublicPath;
|
||||
}
|
||||
/**
|
||||
* Generator options for css modules.
|
||||
*/
|
||||
export interface CssGeneratorOptions {}
|
||||
/**
|
||||
* Parser options for css modules.
|
||||
*/
|
||||
export interface CssParserOptions {}
|
||||
/**
|
||||
* No generator options are supported for this module type.
|
||||
*/
|
||||
|
@ -2776,6 +2772,10 @@ export interface EmptyParserOptions {}
|
|||
* An object with entry point description.
|
||||
*/
|
||||
export interface EntryDescriptionNormalized {
|
||||
/**
|
||||
* Enable/disable creating async chunks that are loaded on demand.
|
||||
*/
|
||||
asyncChunks?: boolean;
|
||||
/**
|
||||
* The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).
|
||||
*/
|
||||
|
@ -2822,6 +2822,47 @@ export interface EntryStaticNormalized {
|
|||
*/
|
||||
[k: string]: EntryDescriptionNormalized;
|
||||
}
|
||||
/**
|
||||
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
|
||||
*/
|
||||
export interface ExperimentsCommon {
|
||||
/**
|
||||
* Support WebAssembly as asynchronous EcmaScript Module.
|
||||
*/
|
||||
asyncWebAssembly?: boolean;
|
||||
/**
|
||||
* Enable backward-compat layer with deprecation warnings for many webpack 4 APIs.
|
||||
*/
|
||||
backCompat?: boolean;
|
||||
/**
|
||||
* Enable additional in memory caching of modules that are unchanged and reference only unchanged modules.
|
||||
*/
|
||||
cacheUnaffected?: boolean;
|
||||
/**
|
||||
* Enable css support.
|
||||
*/
|
||||
css?: boolean;
|
||||
/**
|
||||
* Apply defaults of next major version.
|
||||
*/
|
||||
futureDefaults?: boolean;
|
||||
/**
|
||||
* Enable module layers.
|
||||
*/
|
||||
layers?: boolean;
|
||||
/**
|
||||
* Allow output javascript files as module source type.
|
||||
*/
|
||||
outputModule?: boolean;
|
||||
/**
|
||||
* Support WebAssembly as synchronous EcmaScript Module (outdated).
|
||||
*/
|
||||
syncWebAssembly?: boolean;
|
||||
/**
|
||||
* Allow using top-level-await in EcmaScript Modules.
|
||||
*/
|
||||
topLevelAwait?: boolean;
|
||||
}
|
||||
/**
|
||||
* Data object passed as argument when a function is set for 'externals'.
|
||||
*/
|
||||
|
@ -2855,6 +2896,31 @@ export interface ExternalItemFunctionData {
|
|||
*/
|
||||
request?: string;
|
||||
}
|
||||
/**
|
||||
* Options for building http resources.
|
||||
*/
|
||||
export interface HttpUriOptions {
|
||||
/**
|
||||
* List of allowed URIs (resp. the beginning of them).
|
||||
*/
|
||||
allowedUris: HttpUriOptionsAllowedUris;
|
||||
/**
|
||||
* Location where resource content is stored for lockfile entries. It's also possible to disable storing by passing false.
|
||||
*/
|
||||
cacheLocation?: false | string;
|
||||
/**
|
||||
* When set, anything that would lead to a modification of the lockfile or any resource content, will result in an error.
|
||||
*/
|
||||
frozen?: boolean;
|
||||
/**
|
||||
* Location of the lockfile.
|
||||
*/
|
||||
lockfileLocation?: string;
|
||||
/**
|
||||
* When set, resources of existing lockfile entries will be fetched and entries will be upgraded when resource content has changed.
|
||||
*/
|
||||
upgrade?: boolean;
|
||||
}
|
||||
/**
|
||||
* Parser options for javascript modules.
|
||||
*/
|
||||
|
@ -2875,6 +2941,10 @@ export interface JavascriptParserOptions {
|
|||
* Enable/disable parsing of magic comments in CommonJs syntax.
|
||||
*/
|
||||
commonjsMagicComments?: boolean;
|
||||
/**
|
||||
* Specifies the behavior of invalid export names in "import ... from ..." and "export ... from ...".
|
||||
*/
|
||||
exportsPresence?: "error" | "warn" | "auto" | false;
|
||||
/**
|
||||
* Enable warnings for full dynamic dependencies.
|
||||
*/
|
||||
|
@ -2899,10 +2969,18 @@ export interface JavascriptParserOptions {
|
|||
* Enable/disable parsing of import() syntax.
|
||||
*/
|
||||
import?: boolean;
|
||||
/**
|
||||
* Specifies the behavior of invalid export names in "import ... from ...".
|
||||
*/
|
||||
importExportsPresence?: "error" | "warn" | "auto" | false;
|
||||
/**
|
||||
* Include polyfills or mocks for various node stuff.
|
||||
*/
|
||||
node?: Node;
|
||||
/**
|
||||
* Specifies the behavior of invalid export names in "export ... from ...". This might be useful to disable during the migration from "export ... from ..." to "export type ... from ..." when reexporting types in TypeScript.
|
||||
*/
|
||||
reexportExportsPresence?: "error" | "warn" | "auto" | false;
|
||||
/**
|
||||
* Enable/disable parsing of require.context syntax.
|
||||
*/
|
||||
|
@ -2920,7 +2998,7 @@ export interface JavascriptParserOptions {
|
|||
*/
|
||||
requireJs?: boolean;
|
||||
/**
|
||||
* Emit errors instead of warnings when imported names don't exist in imported module.
|
||||
* Deprecated in favor of "exportsPresence". Emit errors instead of warnings when imported names don't exist in imported module.
|
||||
*/
|
||||
strictExportPresence?: boolean;
|
||||
/**
|
||||
|
@ -2969,6 +3047,66 @@ export interface JavascriptParserOptions {
|
|||
wrappedContextRegExp?: RegExp;
|
||||
[k: string]: any;
|
||||
}
|
||||
/**
|
||||
* Options for the default backend.
|
||||
*/
|
||||
export interface LazyCompilationDefaultBackendOptions {
|
||||
/**
|
||||
* A custom client.
|
||||
*/
|
||||
client?: string;
|
||||
/**
|
||||
* Specifies where to listen to from the server.
|
||||
*/
|
||||
listen?:
|
||||
| number
|
||||
| import("net").ListenOptions
|
||||
| ((server: import("net").Server) => void);
|
||||
/**
|
||||
* Specifies the protocol the client should use to connect to the server.
|
||||
*/
|
||||
protocol?: "http" | "https";
|
||||
/**
|
||||
* Specifies how to create the server handling the EventSource requests.
|
||||
*/
|
||||
server?:
|
||||
| (import("https").ServerOptions | import("http").ServerOptions)
|
||||
| (() => import("net").Server);
|
||||
}
|
||||
/**
|
||||
* Options for compiling entrypoints and import()s only when they are accessed.
|
||||
*/
|
||||
export interface LazyCompilationOptions {
|
||||
/**
|
||||
* Specifies the backend that should be used for handling client keep alive.
|
||||
*/
|
||||
backend?:
|
||||
| (
|
||||
| ((
|
||||
compiler: import("../lib/Compiler"),
|
||||
callback: (
|
||||
err?: Error,
|
||||
api?: import("../lib/hmr/LazyCompilationPlugin").BackendApi
|
||||
) => void
|
||||
) => void)
|
||||
| ((
|
||||
compiler: import("../lib/Compiler")
|
||||
) => Promise<import("../lib/hmr/LazyCompilationPlugin").BackendApi>)
|
||||
)
|
||||
| LazyCompilationDefaultBackendOptions;
|
||||
/**
|
||||
* Enable/disable lazy compilation for entries.
|
||||
*/
|
||||
entries?: boolean;
|
||||
/**
|
||||
* Enable/disable lazy compilation for import() modules.
|
||||
*/
|
||||
imports?: boolean;
|
||||
/**
|
||||
* Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name.
|
||||
*/
|
||||
test?: RegExp | string | ((module: import("../lib/Module")) => boolean);
|
||||
}
|
||||
/**
|
||||
* Options affecting the normal modules (`NormalModuleFactory`).
|
||||
*/
|
||||
|
@ -3006,6 +3144,10 @@ export interface OutputNormalized {
|
|||
* The filename of asset modules as relative path inside the 'output.path' directory.
|
||||
*/
|
||||
assetModuleFilename?: AssetModuleFilename;
|
||||
/**
|
||||
* Enable/disable creating async chunks that are loaded on demand.
|
||||
*/
|
||||
asyncChunks?: boolean;
|
||||
/**
|
||||
* Add charset attribute for script tag.
|
||||
*/
|
||||
|
@ -3042,6 +3184,14 @@ export interface OutputNormalized {
|
|||
* This option enables cross-origin loading of chunks.
|
||||
*/
|
||||
crossOriginLoading?: CrossOriginLoading;
|
||||
/**
|
||||
* Specifies the filename template of non-initial output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.
|
||||
*/
|
||||
cssChunkFilename?: CssChunkFilename;
|
||||
/**
|
||||
* Specifies the filename template of output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.
|
||||
*/
|
||||
cssFilename?: CssFilename;
|
||||
/**
|
||||
* Similar to `output.devtoolModuleFilenameTemplate`, but used in the case of duplicate module identifiers.
|
||||
*/
|
||||
|
@ -3222,7 +3372,7 @@ export interface WebpackOptionsNormalized {
|
|||
/**
|
||||
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
|
||||
*/
|
||||
experiments: Experiments;
|
||||
experiments: ExperimentsNormalized;
|
||||
/**
|
||||
* Specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on `output.libraryTarget`.
|
||||
*/
|
||||
|
@ -3324,6 +3474,32 @@ export interface WebpackOptionsNormalized {
|
|||
*/
|
||||
watchOptions: WatchOptions;
|
||||
}
|
||||
/**
|
||||
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
|
||||
*/
|
||||
export interface ExperimentsExtra {
|
||||
/**
|
||||
* Build http(s): urls using a lockfile and resource content cache.
|
||||
*/
|
||||
buildHttp?: HttpUriAllowedUris | HttpUriOptions;
|
||||
/**
|
||||
* Compile entrypoints and import()s only when they are accessed.
|
||||
*/
|
||||
lazyCompilation?: boolean | LazyCompilationOptions;
|
||||
}
|
||||
/**
|
||||
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
|
||||
*/
|
||||
export interface ExperimentsNormalizedExtra {
|
||||
/**
|
||||
* Build http(s): urls using a lockfile and resource content cache.
|
||||
*/
|
||||
buildHttp?: HttpUriOptions;
|
||||
/**
|
||||
* Compile entrypoints and import()s only when they are accessed.
|
||||
*/
|
||||
lazyCompilation?: LazyCompilationOptions;
|
||||
}
|
||||
/**
|
||||
* If an dependency matches exactly a property of the object, the property value is used as dependency.
|
||||
*/
|
||||
|
|
|
@ -29,7 +29,7 @@ export type LibraryExport = string[] | string;
|
|||
*/
|
||||
export type LibraryName = string[] | string | LibraryCustomUmdObject;
|
||||
/**
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
*/
|
||||
export type LibraryType =
|
||||
| (
|
||||
|
@ -44,6 +44,7 @@ export type LibraryType =
|
|||
| "commonjs"
|
||||
| "commonjs2"
|
||||
| "commonjs-module"
|
||||
| "commonjs-static"
|
||||
| "amd"
|
||||
| "amd-require"
|
||||
| "umd"
|
||||
|
@ -126,7 +127,7 @@ export interface LibraryOptions {
|
|||
*/
|
||||
name?: LibraryName;
|
||||
/**
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
*/
|
||||
type: LibraryType;
|
||||
/**
|
||||
|
|
|
@ -18,6 +18,7 @@ export type ExternalsType =
|
|||
| "commonjs"
|
||||
| "commonjs2"
|
||||
| "commonjs-module"
|
||||
| "commonjs-static"
|
||||
| "amd"
|
||||
| "amd-require"
|
||||
| "umd"
|
||||
|
|
|
@ -29,7 +29,7 @@ export type LibraryExport = string[] | string;
|
|||
*/
|
||||
export type LibraryName = string[] | string | LibraryCustomUmdObject;
|
||||
/**
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
*/
|
||||
export type LibraryType =
|
||||
| (
|
||||
|
@ -44,6 +44,7 @@ export type LibraryType =
|
|||
| "commonjs"
|
||||
| "commonjs2"
|
||||
| "commonjs-module"
|
||||
| "commonjs-static"
|
||||
| "amd"
|
||||
| "amd-require"
|
||||
| "umd"
|
||||
|
@ -70,6 +71,7 @@ export type ExternalsType =
|
|||
| "commonjs"
|
||||
| "commonjs2"
|
||||
| "commonjs-module"
|
||||
| "commonjs-static"
|
||||
| "amd"
|
||||
| "amd-require"
|
||||
| "umd"
|
||||
|
@ -182,7 +184,7 @@ export interface LibraryOptions {
|
|||
*/
|
||||
name?: LibraryName;
|
||||
/**
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
* Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).
|
||||
*/
|
||||
type: LibraryType;
|
||||
/**
|
||||
|
|
|
@ -5,11 +5,23 @@
|
|||
*/
|
||||
|
||||
export type HttpUriPluginOptions = HttpUriOptions;
|
||||
/**
|
||||
* List of allowed URIs (resp. the beginning of them).
|
||||
*/
|
||||
export type HttpUriOptionsAllowedUris = (
|
||||
| RegExp
|
||||
| string
|
||||
| ((uri: string) => boolean)
|
||||
)[];
|
||||
|
||||
/**
|
||||
* Options for building http resources.
|
||||
*/
|
||||
export interface HttpUriOptions {
|
||||
/**
|
||||
* List of allowed URIs (resp. the beginning of them).
|
||||
*/
|
||||
allowedUris: HttpUriOptionsAllowedUris;
|
||||
/**
|
||||
* Location where resource content is stored for lockfile entries. It's also possible to disable storing by passing false.
|
||||
*/
|
||||
|
|
|
@ -4,6 +4,11 @@ module.exports = {
|
|||
// loggingDebug: /HttpUriPlugin/
|
||||
// },
|
||||
experiments: {
|
||||
buildHttp: true
|
||||
buildHttp: [
|
||||
"https://cdn.esm.sh/",
|
||||
"https://cdn.skypack.dev/",
|
||||
"https://jspm.dev/",
|
||||
/^https:\/\/unpkg\.com\/.+\?module$/
|
||||
]
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,536 @@
|
|||
# example.js
|
||||
|
||||
```javascript
|
||||
import "./style.css";
|
||||
import "./style2.css";
|
||||
import { main } from "./style.module.css";
|
||||
import("./lazy-style.css");
|
||||
|
||||
document.getElementsByTagName("main")[0].className = main;
|
||||
```
|
||||
|
||||
# style.css
|
||||
|
||||
```javascript
|
||||
@import "style-imported.css";
|
||||
@import "https://fonts.googleapis.com/css?family=Open+Sans";
|
||||
|
||||
body {
|
||||
background: green;
|
||||
font-family: "Open Sans";
|
||||
}
|
||||
```
|
||||
|
||||
# dist/output.js
|
||||
|
||||
```javascript
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
/******/ var __webpack_modules__ = ({
|
||||
|
||||
/***/ 3:
|
||||
/*!*************************!*\
|
||||
!*** ./images/file.png ***!
|
||||
\*************************/
|
||||
/*! default exports */
|
||||
/*! exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: module, __webpack_require__.p, __webpack_require__.* */
|
||||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||||
|
||||
module.exports = __webpack_require__.p + "89a353e9c515885abd8e.png";
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
```
|
||||
|
||||
<details><summary><code>/* webpack runtime code */</code></summary>
|
||||
|
||||
``` js
|
||||
/************************************************************************/
|
||||
/******/ // The module cache
|
||||
/******/ var __webpack_module_cache__ = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/ // Check if module is in cache
|
||||
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||
/******/ if (cachedModule !== undefined) {
|
||||
/******/ return cachedModule.exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||
/******/ // no module.id needed
|
||||
/******/ // no module.loaded needed
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = __webpack_modules__;
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/ /* webpack/runtime/ensure chunk */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.f = {};
|
||||
/******/ // This file contains only the entry chunk.
|
||||
/******/ // The chunk loading function for additional chunks
|
||||
/******/ __webpack_require__.e = (chunkId) => {
|
||||
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
|
||||
/******/ __webpack_require__.f[key](chunkId, promises);
|
||||
/******/ return promises;
|
||||
/******/ }, []));
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/get css chunk filename */
|
||||
/******/ (() => {
|
||||
/******/ // This function allow to reference async chunks
|
||||
/******/ __webpack_require__.k = (chunkId) => {
|
||||
/******/ // return url for filenames based on template
|
||||
/******/ return "" + chunkId + ".output.css";
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/get javascript chunk filename */
|
||||
/******/ (() => {
|
||||
/******/ // This function allow to reference async chunks
|
||||
/******/ __webpack_require__.u = (chunkId) => {
|
||||
/******/ // return url for filenames based on template
|
||||
/******/ return "" + chunkId + ".output.js";
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/load script */
|
||||
/******/ (() => {
|
||||
/******/ var inProgress = {};
|
||||
/******/ var dataWebpackPrefix = "app:";
|
||||
/******/ // loadScript function to load a script via script tag
|
||||
/******/ __webpack_require__.l = (url, done, key, chunkId) => {
|
||||
/******/ if(inProgress[url]) { inProgress[url].push(done); return; }
|
||||
/******/ var script, needAttach;
|
||||
/******/ if(key !== undefined) {
|
||||
/******/ var scripts = document.getElementsByTagName("script");
|
||||
/******/ for(var i = 0; i < scripts.length; i++) {
|
||||
/******/ var s = scripts[i];
|
||||
/******/ if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; }
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ if(!script) {
|
||||
/******/ needAttach = true;
|
||||
/******/ script = document.createElement('script');
|
||||
/******/
|
||||
/******/ script.charset = 'utf-8';
|
||||
/******/ script.timeout = 120;
|
||||
/******/ if (__webpack_require__.nc) {
|
||||
/******/ script.setAttribute("nonce", __webpack_require__.nc);
|
||||
/******/ }
|
||||
/******/ script.setAttribute("data-webpack", dataWebpackPrefix + key);
|
||||
/******/ script.src = url;
|
||||
/******/ }
|
||||
/******/ inProgress[url] = [done];
|
||||
/******/ var onScriptComplete = (prev, event) => {
|
||||
/******/ // avoid mem leaks in IE.
|
||||
/******/ script.onerror = script.onload = null;
|
||||
/******/ clearTimeout(timeout);
|
||||
/******/ var doneFns = inProgress[url];
|
||||
/******/ delete inProgress[url];
|
||||
/******/ script.parentNode && script.parentNode.removeChild(script);
|
||||
/******/ doneFns && doneFns.forEach((fn) => (fn(event)));
|
||||
/******/ if(prev) return prev(event);
|
||||
/******/ }
|
||||
/******/ ;
|
||||
/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
|
||||
/******/ script.onerror = onScriptComplete.bind(null, script.onerror);
|
||||
/******/ script.onload = onScriptComplete.bind(null, script.onload);
|
||||
/******/ needAttach && document.head.appendChild(script);
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/make namespace object */
|
||||
/******/ (() => {
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = (exports) => {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/publicPath */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.p = "dist/";
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/css loading */
|
||||
/******/ (() => {
|
||||
/******/ // object to store loaded and loading chunks
|
||||
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
||||
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
|
||||
/******/ var installedChunks = {};
|
||||
/******/
|
||||
/******/ var uniqueName = "app";
|
||||
/******/ var loadCssChunkData = (target, link, chunkId) => {
|
||||
/******/ var data, token = "", token2, exports = {}, exportsWithId = [], exportsWithDashes = [], i = 0, cc = 1;
|
||||
/******/ try { if(!link) link = loadStylesheet(chunkId); data = link.sheet.cssRules; data = data[data.length - 1].style; } catch(e) { data = getComputedStyle(document.head); }
|
||||
/******/ data = data.getPropertyValue("--webpack-" + uniqueName + "-" + chunkId);
|
||||
/******/ if(!data) return [];
|
||||
/******/ for(; cc; i++) {
|
||||
/******/ cc = data.charCodeAt(i);
|
||||
/******/ if(cc == 40) { token2 = token; token = ""; }
|
||||
/******/ else if(cc == 41) { exports[token2.replace(/^_/, "")] = token.replace(/^_/, ""); token = ""; }
|
||||
/******/ else if(cc == 47 || cc == 37) { token = token.replace(/^_/, ""); exports[token] = token; exportsWithId.push(token); if(cc == 37) exportsWithDashes.push(token); token = ""; }
|
||||
/******/ else if(!cc || cc == 44) { token = token.replace(/^_/, ""); exportsWithId.forEach((x) => (exports[x] = uniqueName + "-" + token + "-" + exports[x])); exportsWithDashes.forEach((x) => (exports[x] = "--" + exports[x])); __webpack_require__.r(exports); target[token] = ((exports, module) => {
|
||||
/******/ module.exports = exports;
|
||||
/******/ }).bind(null, exports); token = ""; exports = {}; exportsWithId.length = 0; }
|
||||
/******/ else if(cc == 92) { token += data[++i] }
|
||||
/******/ else { token += data[i]; }
|
||||
/******/ }
|
||||
/******/ installedChunks[chunkId] = 0;
|
||||
/******/
|
||||
/******/ }
|
||||
/******/ var loadingAttribute = "data-webpack-loading";
|
||||
/******/ var loadStylesheet = (chunkId, url, done) => {
|
||||
/******/ var link, needAttach, key = "chunk-" + chunkId;
|
||||
/******/
|
||||
/******/ var links = document.getElementsByTagName("link");
|
||||
/******/ for(var i = 0; i < links.length; i++) {
|
||||
/******/ var l = links[i];
|
||||
/******/ if(l.rel == "stylesheet" && (l.href == url || l.getAttribute("href") == url || l.getAttribute("data-webpack") == uniqueName + ":" + key)) { link = l; break; }
|
||||
/******/ }
|
||||
/******/ if(!done) return link;
|
||||
/******/
|
||||
/******/ if(!link) {
|
||||
/******/ needAttach = true;
|
||||
/******/ link = document.createElement('link');
|
||||
/******/ link.setAttribute("data-webpack", uniqueName + ":" + key);
|
||||
/******/ link.setAttribute(loadingAttribute, 1);
|
||||
/******/ link.rel = "stylesheet";
|
||||
/******/ link.href = url;
|
||||
/******/ }
|
||||
/******/ var onLinkComplete = (prev, event) => {
|
||||
/******/ link.onerror = link.onload = null;
|
||||
/******/ link.removeAttribute(loadingAttribute);
|
||||
/******/ clearTimeout(timeout);
|
||||
/******/ if(event && event.type != "load") link.parentNode.removeChild(link)
|
||||
/******/ done(event);
|
||||
/******/ if(prev) return prev(event);
|
||||
/******/ };
|
||||
/******/ if(link.getAttribute(loadingAttribute)) {
|
||||
/******/ var timeout = setTimeout(onLinkComplete.bind(null, undefined, { type: 'timeout', target: link }), 120000);
|
||||
/******/ link.onerror = onLinkComplete.bind(null, link.onerror);
|
||||
/******/ link.onload = onLinkComplete.bind(null, link.onload);
|
||||
/******/ } else onLinkComplete(undefined, { type: 'load', target: link });
|
||||
/******/
|
||||
/******/ needAttach && document.head.appendChild(link);
|
||||
/******/ return link;
|
||||
/******/ };
|
||||
/******/ loadCssChunkData(__webpack_require__.m, 0, 0);
|
||||
/******/
|
||||
/******/ __webpack_require__.f.css = (chunkId, promises) => {
|
||||
/******/ // css chunk loading
|
||||
/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
|
||||
/******/ if(installedChunkData !== 0) { // 0 means "already installed".
|
||||
/******/
|
||||
/******/ // a Promise means "currently loading".
|
||||
/******/ if(installedChunkData) {
|
||||
/******/ promises.push(installedChunkData[2]);
|
||||
/******/ } else {
|
||||
/******/ if(true) { // all chunks have CSS
|
||||
/******/ // setup Promise in chunk cache
|
||||
/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
|
||||
/******/ promises.push(installedChunkData[2] = promise);
|
||||
/******/
|
||||
/******/ // start chunk loading
|
||||
/******/ var url = __webpack_require__.p + __webpack_require__.k(chunkId);
|
||||
/******/ // create error before stack unwound to get useful stacktrace later
|
||||
/******/ var error = new Error();
|
||||
/******/ var loadingEnded = (event) => {
|
||||
/******/ if(__webpack_require__.o(installedChunks, chunkId)) {
|
||||
/******/ installedChunkData = installedChunks[chunkId];
|
||||
/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
|
||||
/******/ if(installedChunkData) {
|
||||
/******/ if(event.type !== "load") {
|
||||
/******/ var errorType = event && event.type;
|
||||
/******/ var realSrc = event && event.target && event.target.src;
|
||||
/******/ error.message = 'Loading css chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
|
||||
/******/ error.name = 'ChunkLoadError';
|
||||
/******/ error.type = errorType;
|
||||
/******/ error.request = realSrc;
|
||||
/******/ installedChunkData[1](error);
|
||||
/******/ } else {
|
||||
/******/ loadCssChunkData(__webpack_require__.m, link, chunkId);
|
||||
/******/ installedChunkData[0]();
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/ var link = loadStylesheet(chunkId, url, loadingEnded);
|
||||
/******/ } else installedChunks[chunkId] = 0;
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // no hmr
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/jsonp chunk loading */
|
||||
/******/ (() => {
|
||||
/******/ // no baseURI
|
||||
/******/
|
||||
/******/ // object to store loaded and loading chunks
|
||||
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
||||
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
|
||||
/******/ var installedChunks = {
|
||||
/******/ 0: 0
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ __webpack_require__.f.j = (chunkId, promises) => {
|
||||
/******/ // JSONP chunk loading for javascript
|
||||
/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
|
||||
/******/ if(installedChunkData !== 0) { // 0 means "already installed".
|
||||
/******/
|
||||
/******/ // a Promise means "currently loading".
|
||||
/******/ if(installedChunkData) {
|
||||
/******/ promises.push(installedChunkData[2]);
|
||||
/******/ } else {
|
||||
/******/ if(0 == chunkId) {
|
||||
/******/ // setup Promise in chunk cache
|
||||
/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
|
||||
/******/ promises.push(installedChunkData[2] = promise);
|
||||
/******/
|
||||
/******/ // start chunk loading
|
||||
/******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId);
|
||||
/******/ // create error before stack unwound to get useful stacktrace later
|
||||
/******/ var error = new Error();
|
||||
/******/ var loadingEnded = (event) => {
|
||||
/******/ if(__webpack_require__.o(installedChunks, chunkId)) {
|
||||
/******/ installedChunkData = installedChunks[chunkId];
|
||||
/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
|
||||
/******/ if(installedChunkData) {
|
||||
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
|
||||
/******/ var realSrc = event && event.target && event.target.src;
|
||||
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
|
||||
/******/ error.name = 'ChunkLoadError';
|
||||
/******/ error.type = errorType;
|
||||
/******/ error.request = realSrc;
|
||||
/******/ installedChunkData[1](error);
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
|
||||
/******/ } else installedChunks[chunkId] = 0;
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // no prefetching
|
||||
/******/
|
||||
/******/ // no preloaded
|
||||
/******/
|
||||
/******/ // no HMR
|
||||
/******/
|
||||
/******/ // no HMR manifest
|
||||
/******/
|
||||
/******/ // no on chunks loaded
|
||||
/******/
|
||||
/******/ // install a JSONP callback for chunk loading
|
||||
/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
|
||||
/******/ var [chunkIds, moreModules, runtime] = data;
|
||||
/******/ // add "moreModules" to the modules object,
|
||||
/******/ // then flag all "chunkIds" as loaded and fire callback
|
||||
/******/ var moduleId, chunkId, i = 0;
|
||||
/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
|
||||
/******/ for(moduleId in moreModules) {
|
||||
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
|
||||
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ if(runtime) var result = runtime(__webpack_require__);
|
||||
/******/ }
|
||||
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
|
||||
/******/ for(;i < chunkIds.length; i++) {
|
||||
/******/ chunkId = chunkIds[i];
|
||||
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
|
||||
/******/ installedChunks[chunkId][0]();
|
||||
/******/ }
|
||||
/******/ installedChunks[chunkId] = 0;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ var chunkLoadingGlobal = self["webpackChunkapp"] = self["webpackChunkapp"] || [];
|
||||
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
|
||||
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
|
||||
/******/ })();
|
||||
/******/
|
||||
/************************************************************************/
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
``` js
|
||||
var __webpack_exports__ = {};
|
||||
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
|
||||
(() => {
|
||||
/*!********************!*\
|
||||
!*** ./example.js ***!
|
||||
\********************/
|
||||
/*! namespace exports */
|
||||
/*! exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.e, __webpack_require__.* */
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var _style_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./style.css */ 1);
|
||||
/* harmony import */ var _style2_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./style2.css */ 5);
|
||||
/* harmony import */ var _style_module_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./style.module.css */ 6);
|
||||
|
||||
|
||||
|
||||
__webpack_require__.e(/*! import() */ 1).then(__webpack_require__.bind(__webpack_require__, /*! ./lazy-style.css */ 7));
|
||||
|
||||
document.getElementsByTagName("main")[0].className = _style_module_css__WEBPACK_IMPORTED_MODULE_2__.main;
|
||||
|
||||
})();
|
||||
|
||||
/******/ })()
|
||||
;
|
||||
```
|
||||
|
||||
# dist/output.css
|
||||
|
||||
```javascript
|
||||
@import url("https://fonts.googleapis.com/css?family=Open+Sans");
|
||||
.img {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
background: url(89a353e9c515885abd8e.png);
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
background: green;
|
||||
font-family: "Open Sans";
|
||||
}
|
||||
|
||||
body {
|
||||
background: red;
|
||||
}
|
||||
|
||||
:root {
|
||||
--app-6-large: 72px;
|
||||
}
|
||||
|
||||
.app-6-main {
|
||||
font-size: var(--app-6-large);
|
||||
color: darkblue;
|
||||
}
|
||||
|
||||
head{--webpack-app-0:_4,_2,_1,_5,large%main/_6;}
|
||||
```
|
||||
|
||||
## production
|
||||
|
||||
```javascript
|
||||
@import url("https://fonts.googleapis.com/css?family=Open+Sans");
|
||||
.img {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
background: url(89a353e9c515885abd8e.png);
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
background: green;
|
||||
font-family: "Open Sans";
|
||||
}
|
||||
|
||||
body {
|
||||
background: red;
|
||||
}
|
||||
|
||||
:root {
|
||||
--app-491-b: 72px;
|
||||
}
|
||||
|
||||
.app-491-D {
|
||||
font-size: var(--app-491-b);
|
||||
color: darkblue;
|
||||
}
|
||||
|
||||
head{--webpack-app-179:_548,_431,_258,_268,b%D/_491;}
|
||||
```
|
||||
|
||||
# dist/1.output.css
|
||||
|
||||
```javascript
|
||||
body {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
head{--webpack-app-1:_7;}
|
||||
```
|
||||
|
||||
# Info
|
||||
|
||||
## Unoptimized
|
||||
|
||||
```
|
||||
assets by chunk 16.9 KiB (name: main)
|
||||
asset output.js 16.5 KiB [emitted] (name: main)
|
||||
asset output.css 385 bytes [emitted] (name: main)
|
||||
asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: images/file.png] (auxiliary name: main)
|
||||
asset 1.output.css 49 bytes [emitted]
|
||||
Entrypoint main 16.9 KiB (14.6 KiB) = output.js 16.5 KiB output.css 385 bytes 1 auxiliary asset
|
||||
chunk (runtime: main) output.js, output.css (main) 218 bytes (javascript) 335 bytes (css) 14.6 KiB (asset) 42 bytes (css-import) 10 KiB (runtime) [entry] [rendered]
|
||||
> ./example.js main
|
||||
runtime modules 10 KiB 9 modules
|
||||
dependent modules 42 bytes (javascript) 14.6 KiB (asset) 335 bytes (css) 42 bytes (css-import) [dependent] 6 modules
|
||||
./example.js 176 bytes [built] [code generated]
|
||||
[no exports]
|
||||
[used exports unknown]
|
||||
entry ./example.js main
|
||||
chunk (runtime: main) 1.output.css 23 bytes
|
||||
> ./lazy-style.css ./example.js 4:0-26
|
||||
./lazy-style.css 23 bytes [built] [code generated]
|
||||
[no exports]
|
||||
[used exports unknown]
|
||||
import() ./lazy-style.css ./example.js 4:0-26
|
||||
webpack 5.66.0 compiled successfully
|
||||
```
|
||||
|
||||
## Production mode
|
||||
|
||||
```
|
||||
assets by chunk 4.25 KiB (name: main)
|
||||
asset output.js 3.87 KiB [emitted] [minimized] (name: main)
|
||||
asset output.css 385 bytes [emitted] (name: main)
|
||||
asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: images/file.png] (auxiliary name: main)
|
||||
asset 159.output.css 53 bytes [emitted]
|
||||
Entrypoint main 4.25 KiB (14.6 KiB) = output.js 3.87 KiB output.css 385 bytes 1 auxiliary asset
|
||||
chunk (runtime: main) 159.output.css 23 bytes
|
||||
> ./lazy-style.css ./example.js 4:0-26
|
||||
./lazy-style.css 23 bytes [built] [code generated]
|
||||
[no exports]
|
||||
import() ./lazy-style.css ./example.js 4:0-26
|
||||
chunk (runtime: main) output.js, output.css (main) 218 bytes (javascript) 335 bytes (css) 14.6 KiB (asset) 42 bytes (css-import) 10 KiB (runtime) [entry] [rendered]
|
||||
> ./example.js main
|
||||
runtime modules 10 KiB 9 modules
|
||||
dependent modules 42 bytes (javascript) 14.6 KiB (asset) 335 bytes (css) 42 bytes (css-import) [dependent] 6 modules
|
||||
./example.js 176 bytes [built] [code generated]
|
||||
[no exports]
|
||||
[no exports used]
|
||||
entry ./example.js main
|
||||
webpack 5.66.0 compiled successfully
|
||||
```
|
|
@ -0,0 +1 @@
|
|||
require("../build-common");
|
|
@ -0,0 +1,6 @@
|
|||
import "./style.css";
|
||||
import "./style2.css";
|
||||
import { main } from "./style.module.css";
|
||||
import("./lazy-style.css");
|
||||
|
||||
document.getElementsByTagName("main")[0].className = main;
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="dist/output.css" data-webpack="app:chunk-0" />
|
||||
</head>
|
||||
<body>
|
||||
<main>Hello World</main>
|
||||
<p class="img"></p>
|
||||
<script src="dist/output.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,3 @@
|
|||
body {
|
||||
color: blue;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
.img {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
background: url("./images/file.png");
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
@import "style-imported.css";
|
||||
@import "https://fonts.googleapis.com/css?family=Open+Sans";
|
||||
|
||||
body {
|
||||
background: green;
|
||||
font-family: "Open Sans";
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
:root {
|
||||
--large: 72px;
|
||||
}
|
||||
|
||||
.main {
|
||||
font-size: var(--large);
|
||||
color: darkblue;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
body {
|
||||
background: red;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
# example.js
|
||||
|
||||
```javascript
|
||||
_{{example.js}}_
|
||||
```
|
||||
|
||||
# style.css
|
||||
|
||||
```javascript
|
||||
_{{style.css}}_
|
||||
```
|
||||
|
||||
# dist/output.js
|
||||
|
||||
```javascript
|
||||
_{{dist/output.js}}_
|
||||
```
|
||||
|
||||
# dist/output.css
|
||||
|
||||
```javascript
|
||||
_{{dist/output.css}}_
|
||||
```
|
||||
|
||||
## production
|
||||
|
||||
```javascript
|
||||
_{{production:dist/output.css}}_
|
||||
```
|
||||
|
||||
# dist/1.output.css
|
||||
|
||||
```javascript
|
||||
_{{dist/1.output.css}}_
|
||||
```
|
||||
|
||||
# Info
|
||||
|
||||
## Unoptimized
|
||||
|
||||
```
|
||||
_{{stdout}}_
|
||||
```
|
||||
|
||||
## Production mode
|
||||
|
||||
```
|
||||
_{{production:stdout}}_
|
||||
```
|
|
@ -0,0 +1,8 @@
|
|||
module.exports = {
|
||||
output: {
|
||||
uniqueName: "app"
|
||||
},
|
||||
experiments: {
|
||||
css: true
|
||||
}
|
||||
};
|
|
@ -67,7 +67,7 @@
|
|||
<!-- A spinner -->
|
||||
<div class="spinner"></div>
|
||||
|
||||
<!-- This script only contains boostrapping logic -->
|
||||
<!-- This script only contains bootstrapping logic -->
|
||||
<!-- It will load all other scripts if necessary -->
|
||||
<script src="/dist/aaa/app.js" async></script>
|
||||
|
||||
|
|
|
@ -9,7 +9,9 @@ exports.keepAlive = function (options) {
|
|||
var active = options.active;
|
||||
var module = options.module;
|
||||
var response;
|
||||
var request = require("http").request(
|
||||
var request = (
|
||||
urlBase.startsWith("https") ? require("https") : require("http")
|
||||
).request(
|
||||
urlBase + data,
|
||||
{
|
||||
agent: false,
|
||||
|
|
|
@ -21,7 +21,7 @@ const {
|
|||
/**
|
||||
* @template T
|
||||
* @callback CallbackCache
|
||||
* @param {WebpackError=} err
|
||||
* @param {(WebpackError | null)=} err
|
||||
* @param {T=} result
|
||||
* @returns {void}
|
||||
*/
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { forEachBail } = require("enhanced-resolve");
|
||||
const asyncLib = require("neo-async");
|
||||
const getLazyHashedEtag = require("./cache/getLazyHashedEtag");
|
||||
const mergeEtags = require("./cache/mergeEtags");
|
||||
|
@ -18,7 +19,7 @@ const mergeEtags = require("./cache/mergeEtags");
|
|||
/**
|
||||
* @template T
|
||||
* @callback CallbackCache
|
||||
* @param {WebpackError=} err
|
||||
* @param {(WebpackError | null)=} err
|
||||
* @param {T=} result
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -26,7 +27,7 @@ const mergeEtags = require("./cache/mergeEtags");
|
|||
/**
|
||||
* @template T
|
||||
* @callback CallbackNormalErrorCache
|
||||
* @param {Error=} err
|
||||
* @param {(Error | null)=} err
|
||||
* @param {T=} result
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -46,15 +47,7 @@ class MultiItemCache {
|
|||
* @returns {void}
|
||||
*/
|
||||
get(callback) {
|
||||
const next = i => {
|
||||
this._items[i].get((err, result) => {
|
||||
if (err) return callback(err);
|
||||
if (result !== undefined) return callback(null, result);
|
||||
if (++i >= this._items.length) return callback();
|
||||
next(i);
|
||||
});
|
||||
};
|
||||
next(0);
|
||||
forEachBail(this._items, (item, callback) => item.get(callback), callback);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -63,8 +63,9 @@ let debugId = 1000;
|
|||
class Chunk {
|
||||
/**
|
||||
* @param {string=} name of chunk being created, is optional (for subclasses)
|
||||
* @param {boolean} backCompat enable backward-compatibility
|
||||
*/
|
||||
constructor(name) {
|
||||
constructor(name, backCompat = true) {
|
||||
/** @type {number | string | null} */
|
||||
this.id = null;
|
||||
/** @type {(number|string)[] | null} */
|
||||
|
@ -79,12 +80,14 @@ class Chunk {
|
|||
this.preventIntegration = false;
|
||||
/** @type {(string | function(PathData, AssetInfo=): string)?} */
|
||||
this.filenameTemplate = undefined;
|
||||
/** @type {(string | function(PathData, AssetInfo=): string)?} */
|
||||
this.cssFilenameTemplate = undefined;
|
||||
/** @private @type {SortableSet<ChunkGroup>} */
|
||||
this._groups = new SortableSet(undefined, compareChunkGroupsByIndex);
|
||||
/** @type {RuntimeSpec} */
|
||||
this.runtime = undefined;
|
||||
/** @type {Set<string>} */
|
||||
this.files = new ChunkFilesSet();
|
||||
this.files = backCompat ? new ChunkFilesSet() : new Set();
|
||||
/** @type {Set<string>} */
|
||||
this.auxiliaryFiles = new Set();
|
||||
/** @type {boolean} */
|
||||
|
|
|
@ -16,6 +16,7 @@ const processAsyncTree = require("./util/processAsyncTree");
|
|||
/** @typedef {import("./Compiler")} Compiler */
|
||||
/** @typedef {import("./logging/Logger").Logger} Logger */
|
||||
/** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */
|
||||
/** @typedef {import("./util/fs").StatsCallback} StatsCallback */
|
||||
|
||||
/** @typedef {(function(string):boolean)|RegExp} IgnoreItem */
|
||||
/** @typedef {function(IgnoreItem): void} AddToIgnoreCallback */
|
||||
|
@ -44,7 +45,7 @@ const validate = createSchemaValidation(
|
|||
* @param {OutputFileSystem} fs filesystem
|
||||
* @param {string} outputPath output path
|
||||
* @param {Set<string>} currentAssets filename of the current assets (must not start with .. or ., must only use / as path separator)
|
||||
* @param {function(Error=, Set<string>=): void} callback returns the filenames of the assets that shouldn't be there
|
||||
* @param {function((Error | null)=, Set<string>=): void} callback returns the filenames of the assets that shouldn't be there
|
||||
* @returns {void}
|
||||
*/
|
||||
const getDiffToFs = (fs, outputPath, currentAssets, callback) => {
|
||||
|
@ -102,6 +103,20 @@ const getDiffToOldAssets = (currentAssets, oldAssets) => {
|
|||
return diff;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {OutputFileSystem} fs filesystem
|
||||
* @param {string} filename path to file
|
||||
* @param {StatsCallback} callback callback for provided filename
|
||||
* @returns {void}
|
||||
*/
|
||||
const doStat = (fs, filename, callback) => {
|
||||
if ("lstat" in fs) {
|
||||
fs.lstat(filename, callback);
|
||||
} else {
|
||||
fs.stat(filename, callback);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {OutputFileSystem} fs filesystem
|
||||
* @param {string} outputPath output path
|
||||
|
@ -150,7 +165,7 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
|
|||
log(`${filename} will be kept`);
|
||||
return process.nextTick(callback);
|
||||
}
|
||||
fs.stat(path, (err, stats) => {
|
||||
doStat(fs, path, (err, stats) => {
|
||||
if (err) return handleError(err);
|
||||
if (!stats.isDirectory()) {
|
||||
push({
|
||||
|
|
|
@ -116,34 +116,34 @@ const { isSourceEqual } = require("./util/source");
|
|||
|
||||
/**
|
||||
* @callback Callback
|
||||
* @param {WebpackError=} err
|
||||
* @param {(WebpackError | null)=} err
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback ModuleCallback
|
||||
* @param {WebpackError=} err
|
||||
* @param {(WebpackError | null)=} err
|
||||
* @param {Module=} result
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback ModuleFactoryResultCallback
|
||||
* @param {WebpackError=} err
|
||||
* @param {(WebpackError | null)=} err
|
||||
* @param {ModuleFactoryResult=} result
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback ModuleOrFactoryResultCallback
|
||||
* @param {WebpackError=} err
|
||||
* @param {(WebpackError | null)=} err
|
||||
* @param {Module | ModuleFactoryResult=} result
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback ExecuteModuleCallback
|
||||
* @param {WebpackError=} err
|
||||
* @param {(WebpackError | null)=} err
|
||||
* @param {ExecuteModuleResult=} result
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -416,10 +416,10 @@ const byLocation = compareSelect(err => err.loc, compareLocations);
|
|||
|
||||
const compareErrors = concatComparators(byModule, byLocation, byMessage);
|
||||
|
||||
/** @type {WeakMap<Dependency, Module & { restoreFromUnsafeCache: Function }>} */
|
||||
/** @type {WeakMap<Dependency, Module & { restoreFromUnsafeCache: Function } | null>} */
|
||||
const unsafeCacheDependencies = new WeakMap();
|
||||
|
||||
/** @type {WeakMap<Module, object>} */
|
||||
/** @type {WeakMap<Module & { restoreFromUnsafeCache: Function }, object>} */
|
||||
const unsafeCacheData = new WeakMap();
|
||||
|
||||
class Compilation {
|
||||
|
@ -429,6 +429,8 @@ class Compilation {
|
|||
* @param {CompilationParams} params the compilation parameters
|
||||
*/
|
||||
constructor(compiler, params) {
|
||||
this._backCompat = compiler._backCompat;
|
||||
|
||||
const getNormalModuleLoader = () => deprecatedNormalModuleLoaderHook(this);
|
||||
/** @typedef {{ additionalAssets?: true | Function }} ProcessAssetsAdditionalOptions */
|
||||
/** @type {AsyncSeriesHook<[CompilationAssets], ProcessAssetsAdditionalOptions>} */
|
||||
|
@ -559,6 +561,7 @@ class Compilation {
|
|||
* @returns {FakeHook<Pick<AsyncSeriesHook<T>, "tap" | "tapAsync" | "tapPromise" | "name">>} fake hook which redirects
|
||||
*/
|
||||
const createProcessAssetsHook = (name, stage, getArgs, code) => {
|
||||
if (!this._backCompat && code) return undefined;
|
||||
const errorMessage =
|
||||
reason => `Can't automatically convert plugin using Compilation.hooks.${name} to Compilation.hooks.processAssets because ${reason}.
|
||||
BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a single Compilation.hooks.processAssets hook.`;
|
||||
|
@ -983,7 +986,6 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
this.asyncEntrypoints = [];
|
||||
/** @type {Set<Chunk>} */
|
||||
this.chunks = new Set();
|
||||
arrayToSetDeprecation(this.chunks, "Compilation.chunks");
|
||||
/** @type {ChunkGroup[]} */
|
||||
this.chunkGroups = [];
|
||||
/** @type {Map<string, ChunkGroup>} */
|
||||
|
@ -992,7 +994,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
this.namedChunks = new Map();
|
||||
/** @type {Set<Module>} */
|
||||
this.modules = new Set();
|
||||
arrayToSetDeprecation(this.modules, "Compilation.modules");
|
||||
if (this._backCompat) {
|
||||
arrayToSetDeprecation(this.chunks, "Compilation.chunks");
|
||||
arrayToSetDeprecation(this.modules, "Compilation.modules");
|
||||
}
|
||||
/** @private @type {Map<string, Module>} */
|
||||
this._modules = new Map();
|
||||
this.records = null;
|
||||
|
@ -1015,7 +1020,9 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
/** @type {Map<DepConstructor, ModuleFactory>} */
|
||||
this.dependencyFactories = new Map();
|
||||
/** @type {DependencyTemplates} */
|
||||
this.dependencyTemplates = new DependencyTemplates();
|
||||
this.dependencyTemplates = new DependencyTemplates(
|
||||
this.outputOptions.hashFunction
|
||||
);
|
||||
this.childrenCounters = {};
|
||||
/** @type {Set<number|string>} */
|
||||
this.usedChunkIds = null;
|
||||
|
@ -1023,8 +1030,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
this.usedModuleIds = null;
|
||||
/** @type {boolean} */
|
||||
this.needAdditionalPass = false;
|
||||
/** @type {Set<Module>} */
|
||||
this._restoredUnsafeCacheEntries = new Set();
|
||||
/** @type {Set<Module & { restoreFromUnsafeCache: Function }>} */
|
||||
this._restoredUnsafeCacheModuleEntries = new Set();
|
||||
/** @type {Map<string, Module & { restoreFromUnsafeCache: Function }>} */
|
||||
this._restoredUnsafeCacheEntries = new Map();
|
||||
/** @type {WeakSet<Module>} */
|
||||
this.builtModules = new WeakSet();
|
||||
/** @type {WeakSet<Module>} */
|
||||
|
@ -1284,7 +1293,8 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
}
|
||||
this._modules.set(identifier, module);
|
||||
this.modules.add(module);
|
||||
ModuleGraph.setModuleGraphForModule(module, this.moduleGraph);
|
||||
if (this._backCompat)
|
||||
ModuleGraph.setModuleGraphForModule(module, this.moduleGraph);
|
||||
if (currentProfile !== undefined) {
|
||||
currentProfile.markIntegrationEnd();
|
||||
}
|
||||
|
@ -1424,9 +1434,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
* @returns {void}
|
||||
*/
|
||||
_processModuleDependencies(module, callback) {
|
||||
/**
|
||||
* @type {Array<{factory: ModuleFactory, dependencies: Dependency[], originModule: Module|null}>}
|
||||
*/
|
||||
/** @type {Array<{factory: ModuleFactory, dependencies: Dependency[], originModule: Module|null}>} */
|
||||
const sortedDependencies = [];
|
||||
|
||||
/** @type {DependenciesBlock} */
|
||||
|
@ -1447,7 +1455,46 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
/** @type {Dependency[]} */
|
||||
let listCacheValue;
|
||||
|
||||
const unsafeRestoredModules = new Set();
|
||||
let inProgressSorting = 1;
|
||||
let inProgressTransitive = 1;
|
||||
|
||||
const onDependenciesSorted = err => {
|
||||
if (err) return callback(err);
|
||||
|
||||
// early exit without changing parallelism back and forth
|
||||
if (sortedDependencies.length === 0 && inProgressTransitive === 1) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
// This is nested so we need to allow one additional task
|
||||
this.processDependenciesQueue.increaseParallelism();
|
||||
|
||||
for (const item of sortedDependencies) {
|
||||
inProgressTransitive++;
|
||||
this.handleModuleCreation(item, err => {
|
||||
// In V8, the Error objects keep a reference to the functions on the stack. These warnings &
|
||||
// errors are created inside closures that keep a reference to the Compilation, so errors are
|
||||
// leaking the Compilation object.
|
||||
if (err && this.bail) {
|
||||
if (inProgressTransitive <= 0) return;
|
||||
inProgressTransitive = -1;
|
||||
// eslint-disable-next-line no-self-assign
|
||||
err.stack = err.stack;
|
||||
onTransitiveTasksFinished(err);
|
||||
return;
|
||||
}
|
||||
if (--inProgressTransitive === 0) onTransitiveTasksFinished();
|
||||
});
|
||||
}
|
||||
if (--inProgressTransitive === 0) onTransitiveTasksFinished();
|
||||
};
|
||||
|
||||
const onTransitiveTasksFinished = err => {
|
||||
if (err) return callback(err);
|
||||
this.processDependenciesQueue.decreaseParallelism();
|
||||
|
||||
return callback();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Dependency} dep dependency
|
||||
|
@ -1458,34 +1505,111 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
this.moduleGraph.setParents(dep, currentBlock, module, index);
|
||||
if (this._unsafeCache) {
|
||||
try {
|
||||
const cachedModule = unsafeCacheDependencies.get(dep);
|
||||
if (cachedModule === null) return;
|
||||
if (cachedModule !== undefined) {
|
||||
if (!this._restoredUnsafeCacheEntries.has(cachedModule)) {
|
||||
const data = unsafeCacheData.get(cachedModule);
|
||||
cachedModule.restoreFromUnsafeCache(
|
||||
data,
|
||||
this.params.normalModuleFactory,
|
||||
this.params
|
||||
const unsafeCachedModule = unsafeCacheDependencies.get(dep);
|
||||
if (unsafeCachedModule === null) return;
|
||||
if (unsafeCachedModule !== undefined) {
|
||||
if (
|
||||
this._restoredUnsafeCacheModuleEntries.has(unsafeCachedModule)
|
||||
) {
|
||||
this._handleExistingModuleFromUnsafeCache(
|
||||
module,
|
||||
dep,
|
||||
unsafeCachedModule
|
||||
);
|
||||
this._restoredUnsafeCacheEntries.add(cachedModule);
|
||||
if (!this.modules.has(cachedModule)) {
|
||||
this._handleNewModuleFromUnsafeCache(module, dep, cachedModule);
|
||||
unsafeRestoredModules.add(cachedModule);
|
||||
return;
|
||||
}
|
||||
const identifier = unsafeCachedModule.identifier();
|
||||
const cachedModule =
|
||||
this._restoredUnsafeCacheEntries.get(identifier);
|
||||
if (cachedModule !== undefined) {
|
||||
// update unsafe cache to new module
|
||||
unsafeCacheDependencies.set(dep, cachedModule);
|
||||
this._handleExistingModuleFromUnsafeCache(
|
||||
module,
|
||||
dep,
|
||||
cachedModule
|
||||
);
|
||||
return;
|
||||
}
|
||||
inProgressSorting++;
|
||||
this._modulesCache.get(identifier, null, (err, cachedModule) => {
|
||||
if (err) {
|
||||
if (inProgressSorting <= 0) return;
|
||||
inProgressSorting = -1;
|
||||
onDependenciesSorted(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this._handleExistingModuleFromUnsafeCache(
|
||||
module,
|
||||
dep,
|
||||
cachedModule
|
||||
);
|
||||
try {
|
||||
if (!this._restoredUnsafeCacheEntries.has(identifier)) {
|
||||
const data = unsafeCacheData.get(cachedModule);
|
||||
if (data === undefined) {
|
||||
processDependencyForResolving(dep);
|
||||
if (--inProgressSorting === 0) onDependenciesSorted();
|
||||
return;
|
||||
}
|
||||
if (cachedModule !== unsafeCachedModule) {
|
||||
unsafeCacheDependencies.set(dep, cachedModule);
|
||||
}
|
||||
cachedModule.restoreFromUnsafeCache(
|
||||
data,
|
||||
this.params.normalModuleFactory,
|
||||
this.params
|
||||
);
|
||||
this._restoredUnsafeCacheEntries.set(
|
||||
identifier,
|
||||
cachedModule
|
||||
);
|
||||
this._restoredUnsafeCacheModuleEntries.add(cachedModule);
|
||||
if (!this.modules.has(cachedModule)) {
|
||||
inProgressTransitive++;
|
||||
this._handleNewModuleFromUnsafeCache(
|
||||
module,
|
||||
dep,
|
||||
cachedModule,
|
||||
err => {
|
||||
if (err) {
|
||||
if (inProgressTransitive <= 0) return;
|
||||
inProgressTransitive = -1;
|
||||
onTransitiveTasksFinished(err);
|
||||
}
|
||||
if (--inProgressTransitive === 0)
|
||||
return onTransitiveTasksFinished();
|
||||
}
|
||||
);
|
||||
if (--inProgressSorting === 0) onDependenciesSorted();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (unsafeCachedModule !== cachedModule) {
|
||||
unsafeCacheDependencies.set(dep, cachedModule);
|
||||
}
|
||||
this._handleExistingModuleFromUnsafeCache(
|
||||
module,
|
||||
dep,
|
||||
cachedModule
|
||||
); // a3
|
||||
} catch (err) {
|
||||
if (inProgressSorting <= 0) return;
|
||||
inProgressSorting = -1;
|
||||
onDependenciesSorted(err);
|
||||
return;
|
||||
}
|
||||
if (--inProgressSorting === 0) onDependenciesSorted();
|
||||
});
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
processDependencyForResolving(dep);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Dependency} dep dependency
|
||||
* @returns {void}
|
||||
*/
|
||||
const processDependencyForResolving = dep => {
|
||||
const resourceIdent = dep.getResourceIdentifier();
|
||||
if (resourceIdent !== undefined && resourceIdent !== null) {
|
||||
const category = dep.category;
|
||||
|
@ -1570,68 +1694,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
return callback(e);
|
||||
}
|
||||
|
||||
if (sortedDependencies.length === 0 && unsafeRestoredModules.size === 0) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
// This is nested so we need to allow one additional task
|
||||
this.processDependenciesQueue.increaseParallelism();
|
||||
|
||||
const processSortedDependency = (item, callback) => {
|
||||
this.handleModuleCreation(item, err => {
|
||||
// In V8, the Error objects keep a reference to the functions on the stack. These warnings &
|
||||
// errors are created inside closures that keep a reference to the Compilation, so errors are
|
||||
// leaking the Compilation object.
|
||||
if (err && this.bail) {
|
||||
// eslint-disable-next-line no-self-assign
|
||||
err.stack = err.stack;
|
||||
return callback(err);
|
||||
}
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
const processUnsafeRestoredModule = (item, callback) => {
|
||||
this._handleModuleBuildAndDependencies(module, item, true, callback);
|
||||
};
|
||||
|
||||
const finalCallback = err => {
|
||||
this.processDependenciesQueue.decreaseParallelism();
|
||||
|
||||
return callback(err);
|
||||
};
|
||||
|
||||
if (sortedDependencies.length === 0) {
|
||||
asyncLib.forEach(
|
||||
unsafeRestoredModules,
|
||||
processUnsafeRestoredModule,
|
||||
finalCallback
|
||||
);
|
||||
} else if (unsafeRestoredModules.size === 0) {
|
||||
asyncLib.forEach(
|
||||
sortedDependencies,
|
||||
processSortedDependency,
|
||||
finalCallback
|
||||
);
|
||||
} else {
|
||||
asyncLib.parallel(
|
||||
[
|
||||
cb =>
|
||||
asyncLib.forEach(
|
||||
unsafeRestoredModules,
|
||||
processUnsafeRestoredModule,
|
||||
cb
|
||||
),
|
||||
cb =>
|
||||
asyncLib.forEach(sortedDependencies, processSortedDependency, cb)
|
||||
],
|
||||
finalCallback
|
||||
);
|
||||
}
|
||||
if (--inProgressSorting === 0) onDependenciesSorted();
|
||||
}
|
||||
|
||||
_handleNewModuleFromUnsafeCache(originModule, dependency, module) {
|
||||
_handleNewModuleFromUnsafeCache(originModule, dependency, module, callback) {
|
||||
const moduleGraph = this.moduleGraph;
|
||||
|
||||
moduleGraph.setResolvedModule(originModule, dependency, module);
|
||||
|
@ -1643,7 +1709,15 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
|
||||
this._modules.set(module.identifier(), module);
|
||||
this.modules.add(module);
|
||||
ModuleGraph.setModuleGraphForModule(module, this.moduleGraph);
|
||||
if (this._backCompat)
|
||||
ModuleGraph.setModuleGraphForModule(module, this.moduleGraph);
|
||||
|
||||
this._handleModuleBuildAndDependencies(
|
||||
originModule,
|
||||
module,
|
||||
true,
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
_handleExistingModuleFromUnsafeCache(originModule, dependency, module) {
|
||||
|
@ -1747,20 +1821,24 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
/** @type {any} */ (module).restoreFromUnsafeCache &&
|
||||
this._unsafeCachePredicate(module)
|
||||
) {
|
||||
const unsafeCacheableModule =
|
||||
/** @type {Module & { restoreFromUnsafeCache: Function }} */ (
|
||||
module
|
||||
);
|
||||
for (let i = 0; i < dependencies.length; i++) {
|
||||
const dependency = dependencies[i];
|
||||
moduleGraph.setResolvedModule(
|
||||
connectOrigin ? originModule : null,
|
||||
dependency,
|
||||
module
|
||||
);
|
||||
unsafeCacheDependencies.set(
|
||||
dependency,
|
||||
/** @type {any} */ (module)
|
||||
unsafeCacheableModule
|
||||
);
|
||||
unsafeCacheDependencies.set(dependency, unsafeCacheableModule);
|
||||
}
|
||||
if (!unsafeCacheData.has(module)) {
|
||||
unsafeCacheData.set(module, module.getUnsafeCacheData());
|
||||
if (!unsafeCacheData.has(unsafeCacheableModule)) {
|
||||
unsafeCacheData.set(
|
||||
unsafeCacheableModule,
|
||||
unsafeCacheableModule.getUnsafeCacheData()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
applyFactoryResultDependencies();
|
||||
|
@ -1814,7 +1892,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
creatingModuleDuringBuildSet
|
||||
);
|
||||
}
|
||||
creatingModuleDuringBuildSet.add(originModule);
|
||||
creatingModuleDuringBuildSet.add(module);
|
||||
|
||||
// When building is blocked by another module
|
||||
// search for a cycle, cancel the cycle by throwing
|
||||
|
@ -2348,9 +2426,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
let statNew = 0;
|
||||
/**
|
||||
* @param {Module} module module
|
||||
* @returns {{ modules?: Map<Module, string | number | undefined>, blocks?: (string | number)[] }} references
|
||||
* @returns {{ id: string | number, modules?: Map<Module, string | number | undefined>, blocks?: (string | number)[] }} references
|
||||
*/
|
||||
const computeReferences = module => {
|
||||
const id = chunkGraph.getModuleId(module);
|
||||
/** @type {Map<Module, string | number | undefined>} */
|
||||
let modules = undefined;
|
||||
/** @type {(string | number)[] | undefined} */
|
||||
|
@ -2378,16 +2457,18 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
queue.push.apply(queue, block.blocks);
|
||||
}
|
||||
}
|
||||
return { modules, blocks };
|
||||
return { id, modules, blocks };
|
||||
};
|
||||
/**
|
||||
* @param {Module} module module
|
||||
* @param {Object} references references
|
||||
* @param {string | number} references.id id
|
||||
* @param {Map<Module, string | number>=} references.modules modules
|
||||
* @param {(string | number)[]=} references.blocks blocks
|
||||
* @returns {boolean} ok?
|
||||
*/
|
||||
const compareReferences = (module, { modules, blocks }) => {
|
||||
const compareReferences = (module, { id, modules, blocks }) => {
|
||||
if (id !== chunkGraph.getModuleId(module)) return false;
|
||||
if (modules !== undefined) {
|
||||
for (const [module, id] of modules) {
|
||||
if (chunkGraph.getModuleId(module) !== id) return false;
|
||||
|
@ -2413,7 +2494,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
};
|
||||
|
||||
for (const [module, memCache] of moduleMemCaches) {
|
||||
/** @type {{ references: { modules?: Map<Module, string | number | undefined>, blocks?: (string | number)[]}, memCache: WeakTupleMap<any[], any> }} */
|
||||
/** @type {{ references: { id: string | number, modules?: Map<Module, string | number | undefined>, blocks?: (string | number)[]}, memCache: WeakTupleMap<any[], any> }} */
|
||||
const cache = memCache.get(key);
|
||||
if (cache === undefined) {
|
||||
const memCache2 = new WeakTupleMap();
|
||||
|
@ -2708,8 +2789,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
);
|
||||
this.chunkGraph = chunkGraph;
|
||||
|
||||
for (const module of this.modules) {
|
||||
ChunkGraph.setChunkGraphForModule(module, chunkGraph);
|
||||
if (this._backCompat) {
|
||||
for (const module of this.modules) {
|
||||
ChunkGraph.setChunkGraphForModule(module, chunkGraph);
|
||||
}
|
||||
}
|
||||
|
||||
this.hooks.seal.call();
|
||||
|
@ -2976,14 +3059,16 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|||
}
|
||||
this.hooks.afterProcessAssets.call(this.assets);
|
||||
this.logger.timeEnd("process assets");
|
||||
this.assets = soonFrozenObjectDeprecation(
|
||||
this.assets,
|
||||
"Compilation.assets",
|
||||
"DEP_WEBPACK_COMPILATION_ASSETS",
|
||||
`BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
|
||||
this.assets = this._backCompat
|
||||
? soonFrozenObjectDeprecation(
|
||||
this.assets,
|
||||
"Compilation.assets",
|
||||
"DEP_WEBPACK_COMPILATION_ASSETS",
|
||||
`BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
|
||||
Do changes to assets earlier, e. g. in Compilation.hooks.processAssets.
|
||||
Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.`
|
||||
);
|
||||
)
|
||||
: Object.freeze(this.assets);
|
||||
|
||||
this.summarizeDependencies();
|
||||
if (shouldRecord) {
|
||||
|
@ -3110,47 +3195,87 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|||
this;
|
||||
const results = this.codeGenerationResults;
|
||||
const errors = [];
|
||||
asyncLib.eachLimit(
|
||||
jobs,
|
||||
this.options.parallelism,
|
||||
({ module, hash, runtime, runtimes }, callback) => {
|
||||
this._codeGenerationModule(
|
||||
module,
|
||||
runtime,
|
||||
runtimes,
|
||||
hash,
|
||||
dependencyTemplates,
|
||||
chunkGraph,
|
||||
moduleGraph,
|
||||
runtimeTemplate,
|
||||
errors,
|
||||
results,
|
||||
(err, codeGenerated) => {
|
||||
if (codeGenerated) statModulesGenerated++;
|
||||
else statModulesFromCache++;
|
||||
callback(err);
|
||||
/** @type {Set<Module> | undefined} */
|
||||
let notCodeGeneratedModules = undefined;
|
||||
const runIteration = () => {
|
||||
let delayedJobs = [];
|
||||
let delayedModules = new Set();
|
||||
asyncLib.eachLimit(
|
||||
jobs,
|
||||
this.options.parallelism,
|
||||
(job, callback) => {
|
||||
const { module } = job;
|
||||
const { codeGenerationDependencies } = module;
|
||||
if (codeGenerationDependencies !== undefined) {
|
||||
if (
|
||||
notCodeGeneratedModules === undefined ||
|
||||
codeGenerationDependencies.some(dep => {
|
||||
const referencedModule = moduleGraph.getModule(dep);
|
||||
return notCodeGeneratedModules.has(referencedModule);
|
||||
})
|
||||
) {
|
||||
delayedJobs.push(job);
|
||||
delayedModules.add(module);
|
||||
return callback();
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
err => {
|
||||
if (err) return callback(err);
|
||||
if (errors.length > 0) {
|
||||
errors.sort(
|
||||
compareSelect(err => err.module, compareModulesByIdentifier)
|
||||
const { hash, runtime, runtimes } = job;
|
||||
this._codeGenerationModule(
|
||||
module,
|
||||
runtime,
|
||||
runtimes,
|
||||
hash,
|
||||
dependencyTemplates,
|
||||
chunkGraph,
|
||||
moduleGraph,
|
||||
runtimeTemplate,
|
||||
errors,
|
||||
results,
|
||||
(err, codeGenerated) => {
|
||||
if (codeGenerated) statModulesGenerated++;
|
||||
else statModulesFromCache++;
|
||||
callback(err);
|
||||
}
|
||||
);
|
||||
for (const error of errors) {
|
||||
this.errors.push(error);
|
||||
},
|
||||
err => {
|
||||
if (err) return callback(err);
|
||||
if (delayedJobs.length > 0) {
|
||||
if (delayedJobs.length === jobs.length) {
|
||||
return callback(
|
||||
new Error(
|
||||
`Unable to make progress during code generation because of circular code generation dependency: ${Array.from(
|
||||
delayedModules,
|
||||
m => m.identifier()
|
||||
).join(", ")}`
|
||||
)
|
||||
);
|
||||
}
|
||||
jobs = delayedJobs;
|
||||
delayedJobs = [];
|
||||
notCodeGeneratedModules = delayedModules;
|
||||
delayedModules = new Set();
|
||||
return runIteration();
|
||||
}
|
||||
if (errors.length > 0) {
|
||||
errors.sort(
|
||||
compareSelect(err => err.module, compareModulesByIdentifier)
|
||||
);
|
||||
for (const error of errors) {
|
||||
this.errors.push(error);
|
||||
}
|
||||
}
|
||||
this.logger.log(
|
||||
`${Math.round(
|
||||
(100 * statModulesGenerated) /
|
||||
(statModulesGenerated + statModulesFromCache)
|
||||
)}% code generated (${statModulesGenerated} generated, ${statModulesFromCache} from cache)`
|
||||
);
|
||||
callback();
|
||||
}
|
||||
this.logger.log(
|
||||
`${Math.round(
|
||||
(100 * statModulesGenerated) /
|
||||
(statModulesGenerated + statModulesFromCache)
|
||||
)}% code generated (${statModulesGenerated} generated, ${statModulesFromCache} from cache)`
|
||||
);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
);
|
||||
};
|
||||
runIteration();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3200,7 +3325,8 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|||
moduleGraph,
|
||||
dependencyTemplates,
|
||||
runtimeTemplate,
|
||||
runtime
|
||||
runtime,
|
||||
codeGenerationResults: results
|
||||
});
|
||||
} catch (err) {
|
||||
errors.push(new CodeGenerationError(module, err));
|
||||
|
@ -3384,7 +3510,8 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|||
*/
|
||||
addRuntimeModule(chunk, module, chunkGraph = this.chunkGraph) {
|
||||
// Deprecated ModuleGraph association
|
||||
ModuleGraph.setModuleGraphForModule(module, this.moduleGraph);
|
||||
if (this._backCompat)
|
||||
ModuleGraph.setModuleGraphForModule(module, this.moduleGraph);
|
||||
|
||||
// add it to the list
|
||||
this.modules.add(module);
|
||||
|
@ -3428,10 +3555,11 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|||
}
|
||||
|
||||
/**
|
||||
* If `module` is passed, `loc` and `request` must also be passed.
|
||||
* @param {string | ChunkGroupOptions} groupOptions options for the chunk group
|
||||
* @param {Module} module the module the references the chunk group
|
||||
* @param {DependencyLocation} loc the location from with the chunk group is referenced (inside of module)
|
||||
* @param {string} request the request from which the the chunk group is referenced
|
||||
* @param {Module=} module the module the references the chunk group
|
||||
* @param {DependencyLocation=} loc the location from with the chunk group is referenced (inside of module)
|
||||
* @param {string=} request the request from which the the chunk group is referenced
|
||||
* @returns {ChunkGroup} the new or existing chunk group
|
||||
*/
|
||||
addChunkInGroup(groupOptions, module, loc, request) {
|
||||
|
@ -3520,9 +3648,10 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|||
return chunk;
|
||||
}
|
||||
}
|
||||
const chunk = new Chunk(name);
|
||||
const chunk = new Chunk(name, this._backCompat);
|
||||
this.chunks.add(chunk);
|
||||
ChunkGraph.setChunkGraphForChunk(chunk, this.chunkGraph);
|
||||
if (this._backCompat)
|
||||
ChunkGraph.setChunkGraphForChunk(chunk, this.chunkGraph);
|
||||
if (name) {
|
||||
this.namedChunks.set(name, chunk);
|
||||
}
|
||||
|
@ -4618,21 +4747,18 @@ This prevents using hashes of each other and should be avoided.`);
|
|||
* @returns {void}
|
||||
*/
|
||||
(module, push, callback) => {
|
||||
this.addModuleQueue.waitFor(module, err => {
|
||||
this.buildQueue.waitFor(module, err => {
|
||||
if (err) return callback(err);
|
||||
this.buildQueue.waitFor(module, err => {
|
||||
this.processDependenciesQueue.waitFor(module, err => {
|
||||
if (err) return callback(err);
|
||||
this.processDependenciesQueue.waitFor(module, err => {
|
||||
if (err) return callback(err);
|
||||
for (const {
|
||||
module: m
|
||||
} of this.moduleGraph.getOutgoingConnections(module)) {
|
||||
const size = modules.size;
|
||||
modules.add(m);
|
||||
if (modules.size !== size) push(m);
|
||||
}
|
||||
callback();
|
||||
});
|
||||
for (const { module: m } of this.moduleGraph.getOutgoingConnections(
|
||||
module
|
||||
)) {
|
||||
const size = modules.size;
|
||||
modules.add(m);
|
||||
if (modules.size !== size) push(m);
|
||||
}
|
||||
callback();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -4649,7 +4775,7 @@ This prevents using hashes of each other and should be avoided.`);
|
|||
this.outputOptions;
|
||||
const runtimeTemplate = this.runtimeTemplate;
|
||||
|
||||
const chunk = new Chunk("build time chunk");
|
||||
const chunk = new Chunk("build time chunk", this._backCompat);
|
||||
chunk.id = chunk.name;
|
||||
chunk.ids = [chunk.id];
|
||||
chunk.runtime = runtime;
|
||||
|
|
|
@ -58,13 +58,13 @@ const { isSourceEqual } = require("./util/source");
|
|||
/**
|
||||
* @template T
|
||||
* @callback Callback
|
||||
* @param {Error=} err
|
||||
* @param {(Error | null)=} err
|
||||
* @param {T=} result
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback RunAsChildCallback
|
||||
* @param {Error=} err
|
||||
* @param {(Error | null)=} err
|
||||
* @param {Chunk[]=} entries
|
||||
* @param {Compilation=} compilation
|
||||
*/
|
||||
|
@ -119,8 +119,9 @@ const includesHash = (filename, hashes) => {
|
|||
class Compiler {
|
||||
/**
|
||||
* @param {string} context the compilation path
|
||||
* @param {WebpackOptions} options options
|
||||
*/
|
||||
constructor(context) {
|
||||
constructor(context, options = /** @type {WebpackOptions} */ ({})) {
|
||||
this.hooks = Object.freeze({
|
||||
/** @type {SyncHook<[]>} */
|
||||
initialize: new SyncHook([]),
|
||||
|
@ -219,9 +220,9 @@ class Compiler {
|
|||
/** @type {string|null} */
|
||||
this.recordsOutputPath = null;
|
||||
this.records = {};
|
||||
/** @type {Set<string>} */
|
||||
/** @type {Set<string | RegExp>} */
|
||||
this.managedPaths = new Set();
|
||||
/** @type {Set<string>} */
|
||||
/** @type {Set<string | RegExp>} */
|
||||
this.immutablePaths = new Set();
|
||||
|
||||
/** @type {ReadonlySet<string>} */
|
||||
|
@ -240,8 +241,7 @@ class Compiler {
|
|||
|
||||
this.infrastructureLogger = undefined;
|
||||
|
||||
/** @type {WebpackOptions} */
|
||||
this.options = /** @type {WebpackOptions} */ ({});
|
||||
this.options = options;
|
||||
|
||||
this.context = context;
|
||||
|
||||
|
@ -263,6 +263,8 @@ class Compiler {
|
|||
/** @type {boolean} */
|
||||
this.watchMode = false;
|
||||
|
||||
this._backCompat = this.options.experiments.backCompat !== false;
|
||||
|
||||
/** @type {Compilation} */
|
||||
this._lastCompilation = undefined;
|
||||
/** @type {NormalModuleFactory} */
|
||||
|
@ -963,7 +965,13 @@ ${other}`);
|
|||
outputOptions,
|
||||
plugins
|
||||
) {
|
||||
const childCompiler = new Compiler(this.context);
|
||||
const childCompiler = new Compiler(this.context, {
|
||||
...this.options,
|
||||
output: {
|
||||
...this.options.output,
|
||||
...outputOptions
|
||||
}
|
||||
});
|
||||
childCompiler.name = compilerName;
|
||||
childCompiler.outputPath = this.outputPath;
|
||||
childCompiler.inputFileSystem = this.inputFileSystem;
|
||||
|
@ -976,6 +984,7 @@ ${other}`);
|
|||
childCompiler.fsStartTime = this.fsStartTime;
|
||||
childCompiler.cache = this.cache;
|
||||
childCompiler.compilerPath = `${this.compilerPath}${compilerName}|${compilerIndex}|`;
|
||||
childCompiler._backCompat = this._backCompat;
|
||||
|
||||
const relativeCompilerName = makePathsRelative(
|
||||
this.context,
|
||||
|
@ -991,13 +1000,6 @@ ${other}`);
|
|||
this.records[relativeCompilerName].push((childCompiler.records = {}));
|
||||
}
|
||||
|
||||
childCompiler.options = {
|
||||
...this.options,
|
||||
output: {
|
||||
...this.options.output,
|
||||
...outputOptions
|
||||
}
|
||||
};
|
||||
childCompiler.parentCompilation = compilation;
|
||||
childCompiler.root = this.root;
|
||||
if (Array.isArray(plugins)) {
|
||||
|
|
|
@ -71,7 +71,7 @@ const makeSerializable = require("./util/makeSerializable");
|
|||
|
||||
/**
|
||||
* @callback ResolveDependenciesCallback
|
||||
* @param {Error=} err
|
||||
* @param {(Error | null)=} err
|
||||
* @param {ContextElementDependency[]=} dependencies
|
||||
*/
|
||||
|
||||
|
@ -149,12 +149,9 @@ class ContextModule extends Module {
|
|||
this.resolveDependencies = undefined;
|
||||
}
|
||||
|
||||
prettyRegExp(regexString) {
|
||||
// remove the "/" at the front and the beginning
|
||||
// "/foo/" -> "foo"
|
||||
return regexString
|
||||
.substring(1, regexString.length - 1)
|
||||
.replace(/!/g, "%21");
|
||||
_prettyRegExp(regexString, stripSlash = true) {
|
||||
const str = (regexString + "").replace(/!/g, "%21").replace(/\|/g, "%7C");
|
||||
return stripSlash ? str.substring(1, str.length - 1) : str;
|
||||
}
|
||||
|
||||
_createIdentifier() {
|
||||
|
@ -175,13 +172,19 @@ class ContextModule extends Module {
|
|||
identifier += `|${this.options.addon}`;
|
||||
}
|
||||
if (this.options.regExp) {
|
||||
identifier += `|${this.options.regExp}`;
|
||||
identifier += `|${this._prettyRegExp(this.options.regExp, false)}`;
|
||||
}
|
||||
if (this.options.include) {
|
||||
identifier += `|include: ${this.options.include}`;
|
||||
identifier += `|include: ${this._prettyRegExp(
|
||||
this.options.include,
|
||||
false
|
||||
)}`;
|
||||
}
|
||||
if (this.options.exclude) {
|
||||
identifier += `|exclude: ${this.options.exclude}`;
|
||||
identifier += `|exclude: ${this._prettyRegExp(
|
||||
this.options.exclude,
|
||||
false
|
||||
)}`;
|
||||
}
|
||||
if (this.options.referencedExports) {
|
||||
identifier += `|referencedExports: ${JSON.stringify(
|
||||
|
@ -231,13 +234,13 @@ class ContextModule extends Module {
|
|||
identifier += ` ${requestShortener.shorten(this.options.addon)}`;
|
||||
}
|
||||
if (this.options.regExp) {
|
||||
identifier += ` ${this.prettyRegExp(this.options.regExp + "")}`;
|
||||
identifier += ` ${this._prettyRegExp(this.options.regExp)}`;
|
||||
}
|
||||
if (this.options.include) {
|
||||
identifier += ` include: ${this.prettyRegExp(this.options.include + "")}`;
|
||||
identifier += ` include: ${this._prettyRegExp(this.options.include)}`;
|
||||
}
|
||||
if (this.options.exclude) {
|
||||
identifier += ` exclude: ${this.prettyRegExp(this.options.exclude + "")}`;
|
||||
identifier += ` exclude: ${this._prettyRegExp(this.options.exclude)}`;
|
||||
}
|
||||
if (this.options.referencedExports) {
|
||||
identifier += ` referencedExports: ${this.options.referencedExports
|
||||
|
@ -272,6 +275,7 @@ class ContextModule extends Module {
|
|||
this.context,
|
||||
options.associatedObjectForCache
|
||||
);
|
||||
if (this.layer) identifier = `(${this.layer})/${identifier}`;
|
||||
if (this.options.mode) {
|
||||
identifier += ` ${this.options.mode}`;
|
||||
}
|
||||
|
@ -286,13 +290,13 @@ class ContextModule extends Module {
|
|||
)}`;
|
||||
}
|
||||
if (this.options.regExp) {
|
||||
identifier += ` ${this.prettyRegExp(this.options.regExp + "")}`;
|
||||
identifier += ` ${this._prettyRegExp(this.options.regExp)}`;
|
||||
}
|
||||
if (this.options.include) {
|
||||
identifier += ` include: ${this.prettyRegExp(this.options.include + "")}`;
|
||||
identifier += ` include: ${this._prettyRegExp(this.options.include)}`;
|
||||
}
|
||||
if (this.options.exclude) {
|
||||
identifier += ` exclude: ${this.prettyRegExp(this.options.exclude + "")}`;
|
||||
identifier += ` exclude: ${this._prettyRegExp(this.options.exclude)}`;
|
||||
}
|
||||
if (this.options.referencedExports) {
|
||||
identifier += ` referencedExports: ${this.options.referencedExports
|
||||
|
@ -312,7 +316,7 @@ class ContextModule extends Module {
|
|||
|
||||
/**
|
||||
* @param {NeedBuildContext} context context info
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @returns {void}
|
||||
*/
|
||||
needBuild({ fileSystemInfo }, callback) {
|
||||
|
|
|
@ -151,7 +151,7 @@ const stringifyObj = (
|
|||
case false:
|
||||
return arr ? `;${code}` : `;(${code})`;
|
||||
default:
|
||||
return `Object(${code})`;
|
||||
return `/*#__PURE__*/Object(${code})`;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ class DelegatedModule extends Module {
|
|||
|
||||
/**
|
||||
* @param {NeedBuildContext} context context info
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @returns {void}
|
||||
*/
|
||||
needBuild(context, callback) {
|
||||
|
|
|
@ -172,6 +172,16 @@ class Dependency {
|
|||
this._loc = loc;
|
||||
}
|
||||
|
||||
setLoc(startLine, startColumn, endLine, endColumn) {
|
||||
this._locSL = startLine;
|
||||
this._locSC = startColumn;
|
||||
this._locEL = endLine;
|
||||
this._locEC = endColumn;
|
||||
this._locI = undefined;
|
||||
this._locN = undefined;
|
||||
this._loc = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string | null} an identifier to merge equal requests
|
||||
*/
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
|
||||
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
||||
/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
|
||||
/** @typedef {import("./ConcatenationScope")} ConcatenationScope */
|
||||
/** @typedef {import("./Dependency")} Dependency */
|
||||
/** @typedef {import("./Dependency").RuntimeSpec} RuntimeSpec */
|
||||
|
@ -28,8 +29,16 @@
|
|||
* @property {RuntimeSpec} runtime current runtimes, for which code is generated
|
||||
* @property {InitFragment<GenerateContext>[]} initFragments mutable array of init fragments for the current module
|
||||
* @property {ConcatenationScope=} concatenationScope when in a concatenated module, information about other concatenated modules
|
||||
* @property {CodeGenerationResults} codeGenerationResults the code generation results
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} CssDependencyTemplateContextExtras
|
||||
* @property {Map<string, string>} cssExports the css exports
|
||||
*/
|
||||
|
||||
/** @typedef {DependencyTemplateContext & CssDependencyTemplateContextExtras} CssDependencyTemplateContext */
|
||||
|
||||
class DependencyTemplate {
|
||||
/* istanbul ignore next */
|
||||
/**
|
||||
|
|
|
@ -57,7 +57,7 @@ class DependencyTemplates {
|
|||
}
|
||||
|
||||
clone() {
|
||||
const newInstance = new DependencyTemplates();
|
||||
const newInstance = new DependencyTemplates(this._hashFunction);
|
||||
newInstance._map = new Map(this._map);
|
||||
newInstance._hash = this._hash;
|
||||
return newInstance;
|
||||
|
|
|
@ -96,7 +96,7 @@ class DllModule extends Module {
|
|||
|
||||
/**
|
||||
* @param {NeedBuildContext} context context info
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @returns {void}
|
||||
*/
|
||||
needBuild(context, callback) {
|
||||
|
|
|
@ -64,6 +64,7 @@ class EntryOptionPlugin {
|
|||
dependOn: desc.dependOn,
|
||||
publicPath: desc.publicPath,
|
||||
chunkLoading: desc.chunkLoading,
|
||||
asyncChunks: desc.asyncChunks,
|
||||
wasmLoading: desc.wasmLoading,
|
||||
library: desc.library
|
||||
};
|
||||
|
|
|
@ -53,6 +53,7 @@ const { register } = require("./util/serialization");
|
|||
*/
|
||||
|
||||
const TYPES = new Set(["javascript"]);
|
||||
const CSS_TYPES = new Set(["css-import"]);
|
||||
const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
|
||||
const RUNTIME_REQUIREMENTS_FOR_SCRIPT = new Set([RuntimeGlobals.loadScript]);
|
||||
const RUNTIME_REQUIREMENTS_FOR_MODULE = new Set([
|
||||
|
@ -392,7 +393,7 @@ class ExternalModule extends Module {
|
|||
* @returns {Set<string>} types available (do not mutate)
|
||||
*/
|
||||
getSourceTypes() {
|
||||
return TYPES;
|
||||
return this.externalType === "css-import" ? CSS_TYPES : TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -409,7 +410,9 @@ class ExternalModule extends Module {
|
|||
* @returns {boolean} true, if the chunk is ok for the module
|
||||
*/
|
||||
chunkCondition(chunk, { chunkGraph }) {
|
||||
return chunkGraph.getNumberOfEntryModules(chunk) > 0;
|
||||
return this.externalType === "css-import"
|
||||
? true
|
||||
: chunkGraph.getNumberOfEntryModules(chunk) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -429,7 +432,7 @@ class ExternalModule extends Module {
|
|||
|
||||
/**
|
||||
* @param {NeedBuildContext} context context info
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @returns {void}
|
||||
*/
|
||||
needBuild(context, callback) {
|
||||
|
@ -526,8 +529,14 @@ class ExternalModule extends Module {
|
|||
return { request, externalType };
|
||||
}
|
||||
|
||||
_getSourceData(runtimeTemplate, moduleGraph, chunkGraph, runtime) {
|
||||
const { request, externalType } = this._getRequestAndExternalType();
|
||||
_getSourceData(
|
||||
request,
|
||||
externalType,
|
||||
runtimeTemplate,
|
||||
moduleGraph,
|
||||
chunkGraph,
|
||||
runtime
|
||||
) {
|
||||
switch (externalType) {
|
||||
case "this":
|
||||
case "window":
|
||||
|
@ -536,11 +545,12 @@ class ExternalModule extends Module {
|
|||
case "global":
|
||||
return getSourceForGlobalVariableExternal(
|
||||
request,
|
||||
runtimeTemplate.outputOptions.globalObject
|
||||
runtimeTemplate.globalObject
|
||||
);
|
||||
case "commonjs":
|
||||
case "commonjs2":
|
||||
case "commonjs-module":
|
||||
case "commonjs-static":
|
||||
return getSourceForCommonJsExternal(request);
|
||||
case "node-commonjs":
|
||||
return this.buildInfo.module
|
||||
|
@ -613,60 +623,90 @@ class ExternalModule extends Module {
|
|||
runtime,
|
||||
concatenationScope
|
||||
}) {
|
||||
const sourceData = this._getSourceData(
|
||||
runtimeTemplate,
|
||||
moduleGraph,
|
||||
chunkGraph,
|
||||
runtime
|
||||
);
|
||||
const { request, externalType } = this._getRequestAndExternalType();
|
||||
switch (externalType) {
|
||||
case "asset": {
|
||||
const sources = new Map();
|
||||
sources.set(
|
||||
"javascript",
|
||||
new RawSource(`module.exports = ${JSON.stringify(request)};`)
|
||||
);
|
||||
const data = new Map();
|
||||
data.set("url", request);
|
||||
return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS, data };
|
||||
}
|
||||
case "css-import": {
|
||||
const sources = new Map();
|
||||
sources.set(
|
||||
"css-import",
|
||||
new RawSource(`@import url(${JSON.stringify(request)});`)
|
||||
);
|
||||
return {
|
||||
sources,
|
||||
runtimeRequirements: EMPTY_RUNTIME_REQUIREMENTS
|
||||
};
|
||||
}
|
||||
default: {
|
||||
const sourceData = this._getSourceData(
|
||||
request,
|
||||
externalType,
|
||||
runtimeTemplate,
|
||||
moduleGraph,
|
||||
chunkGraph,
|
||||
runtime
|
||||
);
|
||||
|
||||
let sourceString = sourceData.expression;
|
||||
if (sourceData.iife)
|
||||
sourceString = `(function() { return ${sourceString}; }())`;
|
||||
if (concatenationScope) {
|
||||
sourceString = `${runtimeTemplate.supportsConst() ? "const" : "var"} ${
|
||||
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
||||
} = ${sourceString};`;
|
||||
concatenationScope.registerNamespaceExport(
|
||||
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
||||
);
|
||||
} else {
|
||||
sourceString = `module.exports = ${sourceString};`;
|
||||
}
|
||||
if (sourceData.init) sourceString = `${sourceData.init}\n${sourceString}`;
|
||||
let sourceString = sourceData.expression;
|
||||
if (sourceData.iife)
|
||||
sourceString = `(function() { return ${sourceString}; }())`;
|
||||
if (concatenationScope) {
|
||||
sourceString = `${
|
||||
runtimeTemplate.supportsConst() ? "const" : "var"
|
||||
} ${ConcatenationScope.NAMESPACE_OBJECT_EXPORT} = ${sourceString};`;
|
||||
concatenationScope.registerNamespaceExport(
|
||||
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
||||
);
|
||||
} else {
|
||||
sourceString = `module.exports = ${sourceString};`;
|
||||
}
|
||||
if (sourceData.init)
|
||||
sourceString = `${sourceData.init}\n${sourceString}`;
|
||||
|
||||
let data = undefined;
|
||||
if (sourceData.chunkInitFragments) {
|
||||
data = new Map();
|
||||
data.set("chunkInitFragments", sourceData.chunkInitFragments);
|
||||
}
|
||||
let data = undefined;
|
||||
if (sourceData.chunkInitFragments) {
|
||||
data = new Map();
|
||||
data.set("chunkInitFragments", sourceData.chunkInitFragments);
|
||||
}
|
||||
|
||||
const sources = new Map();
|
||||
if (this.useSourceMap || this.useSimpleSourceMap) {
|
||||
sources.set(
|
||||
"javascript",
|
||||
new OriginalSource(sourceString, this.identifier())
|
||||
);
|
||||
} else {
|
||||
sources.set("javascript", new RawSource(sourceString));
|
||||
}
|
||||
const sources = new Map();
|
||||
if (this.useSourceMap || this.useSimpleSourceMap) {
|
||||
sources.set(
|
||||
"javascript",
|
||||
new OriginalSource(sourceString, this.identifier())
|
||||
);
|
||||
} else {
|
||||
sources.set("javascript", new RawSource(sourceString));
|
||||
}
|
||||
|
||||
let runtimeRequirements = sourceData.runtimeRequirements;
|
||||
if (!concatenationScope) {
|
||||
if (!runtimeRequirements) {
|
||||
runtimeRequirements = RUNTIME_REQUIREMENTS;
|
||||
} else {
|
||||
const set = new Set(runtimeRequirements);
|
||||
set.add(RuntimeGlobals.module);
|
||||
runtimeRequirements = set;
|
||||
let runtimeRequirements = sourceData.runtimeRequirements;
|
||||
if (!concatenationScope) {
|
||||
if (!runtimeRequirements) {
|
||||
runtimeRequirements = RUNTIME_REQUIREMENTS;
|
||||
} else {
|
||||
const set = new Set(runtimeRequirements);
|
||||
set.add(RuntimeGlobals.module);
|
||||
runtimeRequirements = set;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
sources,
|
||||
runtimeRequirements:
|
||||
runtimeRequirements || EMPTY_RUNTIME_REQUIREMENTS,
|
||||
data
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
sources,
|
||||
runtimeRequirements: runtimeRequirements || EMPTY_RUNTIME_REQUIREMENTS,
|
||||
data
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -117,7 +117,7 @@ class ExternalModuleFactoryPlugin {
|
|||
|
||||
/**
|
||||
* @param {Externals} externals externals config
|
||||
* @param {function(Error=, ExternalModule=): void} callback callback
|
||||
* @param {function((Error | null)=, ExternalModule=): void} callback callback
|
||||
* @returns {void}
|
||||
*/
|
||||
const handleExternals = (externals, callback) => {
|
||||
|
|
|
@ -206,17 +206,17 @@ class Snapshot {
|
|||
this._flags = 0;
|
||||
/** @type {number | undefined} */
|
||||
this.startTime = undefined;
|
||||
/** @type {Map<string, FileSystemInfoEntry> | undefined} */
|
||||
/** @type {Map<string, FileSystemInfoEntry | null> | undefined} */
|
||||
this.fileTimestamps = undefined;
|
||||
/** @type {Map<string, string> | undefined} */
|
||||
/** @type {Map<string, string | null> | undefined} */
|
||||
this.fileHashes = undefined;
|
||||
/** @type {Map<string, TimestampAndHash | string> | undefined} */
|
||||
/** @type {Map<string, TimestampAndHash | string | null> | undefined} */
|
||||
this.fileTshs = undefined;
|
||||
/** @type {Map<string, ResolvedContextFileSystemInfoEntry> | undefined} */
|
||||
/** @type {Map<string, ResolvedContextFileSystemInfoEntry | null> | undefined} */
|
||||
this.contextTimestamps = undefined;
|
||||
/** @type {Map<string, string> | undefined} */
|
||||
/** @type {Map<string, string | null> | undefined} */
|
||||
this.contextHashes = undefined;
|
||||
/** @type {Map<string, ResolvedContextTimestampAndHash> | undefined} */
|
||||
/** @type {Map<string, ResolvedContextTimestampAndHash | null> | undefined} */
|
||||
this.contextTshs = undefined;
|
||||
/** @type {Map<string, boolean> | undefined} */
|
||||
this.missingExistence = undefined;
|
||||
|
@ -692,6 +692,11 @@ class SnapshotOptimization {
|
|||
}
|
||||
}
|
||||
|
||||
const parseString = str => {
|
||||
if (str[0] === "'") str = `"${str.slice(1, -1).replace(/"/g, '\\"')}"`;
|
||||
return JSON.parse(str);
|
||||
};
|
||||
|
||||
/* istanbul ignore next */
|
||||
/**
|
||||
* @param {number} mtime mtime
|
||||
|
@ -823,11 +828,10 @@ const getManagedItem = (managedPath, path) => {
|
|||
|
||||
/**
|
||||
* @template {ContextFileSystemInfoEntry | ContextTimestampAndHash} T
|
||||
* @param {T | "ignore"} entry entry
|
||||
* @param {T} entry entry
|
||||
* @returns {T["resolved"] | undefined} the resolved entry
|
||||
*/
|
||||
const getResolvedTimestamp = entry => {
|
||||
if (entry === "ignore") return undefined;
|
||||
if (entry === null) return null;
|
||||
if (entry.resolved !== undefined) return entry.resolved;
|
||||
return entry.symlinks === undefined ? entry : undefined;
|
||||
|
@ -854,8 +858,8 @@ class FileSystemInfo {
|
|||
/**
|
||||
* @param {InputFileSystem} fs file system
|
||||
* @param {Object} options options
|
||||
* @param {Iterable<string>=} options.managedPaths paths that are only managed by a package manager
|
||||
* @param {Iterable<string>=} options.immutablePaths paths that are immutable
|
||||
* @param {Iterable<string | RegExp>=} options.managedPaths paths that are only managed by a package manager
|
||||
* @param {Iterable<string | RegExp>=} options.immutablePaths paths that are immutable
|
||||
* @param {Logger=} options.logger logger used to log invalid snapshots
|
||||
* @param {string | Hash=} options.hashFunction the hash function to use
|
||||
*/
|
||||
|
@ -997,12 +1001,19 @@ class FileSystemInfo {
|
|||
processor: this._getManagedItemDirectoryInfo.bind(this)
|
||||
});
|
||||
this.managedPaths = Array.from(managedPaths);
|
||||
this.managedPathsWithSlash = this.managedPaths.map(p =>
|
||||
join(fs, p, "_").slice(0, -1)
|
||||
this.managedPathsWithSlash = /** @type {string[]} */ (
|
||||
this.managedPaths.filter(p => typeof p === "string")
|
||||
).map(p => join(fs, p, "_").slice(0, -1));
|
||||
|
||||
this.managedPathsRegExps = /** @type {RegExp[]} */ (
|
||||
this.managedPaths.filter(p => typeof p !== "string")
|
||||
);
|
||||
this.immutablePaths = Array.from(immutablePaths);
|
||||
this.immutablePathsWithSlash = this.immutablePaths.map(p =>
|
||||
join(fs, p, "_").slice(0, -1)
|
||||
this.immutablePathsWithSlash = /** @type {string[]} */ (
|
||||
this.immutablePaths.filter(p => typeof p === "string")
|
||||
).map(p => join(fs, p, "_").slice(0, -1));
|
||||
this.immutablePathsRegExps = /** @type {RegExp[]} */ (
|
||||
this.immutablePaths.filter(p => typeof p !== "string")
|
||||
);
|
||||
|
||||
this._cachedDeprecatedFileTimestamps = undefined;
|
||||
|
@ -1174,7 +1185,7 @@ class FileSystemInfo {
|
|||
|
||||
/**
|
||||
* @param {string} path file path
|
||||
* @param {function(WebpackError=, (FileSystemInfoEntry | "ignore" | null)=): void} callback callback function
|
||||
* @param {function((WebpackError | null)=, (FileSystemInfoEntry | "ignore" | null)=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
getFileTimestamp(path, callback) {
|
||||
|
@ -1185,12 +1196,13 @@ class FileSystemInfo {
|
|||
|
||||
/**
|
||||
* @param {string} path context path
|
||||
* @param {function(WebpackError=, (ResolvedContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function
|
||||
* @param {function((WebpackError | null)=, (ResolvedContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
getContextTimestamp(path, callback) {
|
||||
const cache = this._contextTimestamps.get(path);
|
||||
if (cache !== undefined) {
|
||||
if (cache === "ignore") return callback(null, "ignore");
|
||||
const resolved = getResolvedTimestamp(cache);
|
||||
if (resolved !== undefined) return callback(null, resolved);
|
||||
return this._resolveContextTimestamp(cache, callback);
|
||||
|
@ -1205,7 +1217,7 @@ class FileSystemInfo {
|
|||
|
||||
/**
|
||||
* @param {string} path context path
|
||||
* @param {function(WebpackError=, (ContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function
|
||||
* @param {function((WebpackError | null)=, (ContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
_getUnresolvedContextTimestamp(path, callback) {
|
||||
|
@ -1216,7 +1228,7 @@ class FileSystemInfo {
|
|||
|
||||
/**
|
||||
* @param {string} path file path
|
||||
* @param {function(WebpackError=, string=): void} callback callback function
|
||||
* @param {function((WebpackError | null)=, string=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
getFileHash(path, callback) {
|
||||
|
@ -1227,7 +1239,7 @@ class FileSystemInfo {
|
|||
|
||||
/**
|
||||
* @param {string} path context path
|
||||
* @param {function(WebpackError=, string=): void} callback callback function
|
||||
* @param {function((WebpackError | null)=, string=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
getContextHash(path, callback) {
|
||||
|
@ -1247,7 +1259,7 @@ class FileSystemInfo {
|
|||
|
||||
/**
|
||||
* @param {string} path context path
|
||||
* @param {function(WebpackError=, ContextHash=): void} callback callback function
|
||||
* @param {function((WebpackError | null)=, ContextHash=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
_getUnresolvedContextHash(path, callback) {
|
||||
|
@ -1258,7 +1270,7 @@ class FileSystemInfo {
|
|||
|
||||
/**
|
||||
* @param {string} path context path
|
||||
* @param {function(WebpackError=, ResolvedContextTimestampAndHash=): void} callback callback function
|
||||
* @param {function((WebpackError | null)=, ResolvedContextTimestampAndHash=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
getContextTsh(path, callback) {
|
||||
|
@ -1278,7 +1290,7 @@ class FileSystemInfo {
|
|||
|
||||
/**
|
||||
* @param {string} path context path
|
||||
* @param {function(WebpackError=, ContextTimestampAndHash=): void} callback callback function
|
||||
* @param {function((WebpackError | null)=, ContextTimestampAndHash=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
_getUnresolvedContextTsh(path, callback) {
|
||||
|
@ -1318,7 +1330,7 @@ class FileSystemInfo {
|
|||
/**
|
||||
* @param {string} context context directory
|
||||
* @param {Iterable<string>} deps dependencies
|
||||
* @param {function(Error=, ResolveBuildDependenciesResult=): void} callback callback function
|
||||
* @param {function((Error | null)=, ResolveBuildDependenciesResult=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
resolveBuildDependencies(context, deps, callback) {
|
||||
|
@ -1650,17 +1662,13 @@ class FileSystemInfo {
|
|||
let dependency;
|
||||
if (imp.d === -1) {
|
||||
// import ... from "..."
|
||||
dependency = JSON.parse(
|
||||
dependency = parseString(
|
||||
source.substring(imp.s - 1, imp.e + 1)
|
||||
);
|
||||
} else if (imp.d > -1) {
|
||||
// import()
|
||||
let expr = source.substring(imp.s, imp.e).trim();
|
||||
if (expr[0] === "'")
|
||||
expr = `"${expr
|
||||
.slice(1, -1)
|
||||
.replace(/"/g, '\\"')}"`;
|
||||
dependency = JSON.parse(expr);
|
||||
dependency = parseString(expr);
|
||||
} else {
|
||||
// e.g. import.meta
|
||||
continue;
|
||||
|
@ -1790,7 +1798,7 @@ class FileSystemInfo {
|
|||
|
||||
/**
|
||||
* @param {Map<string, string | false>} resolveResults results from resolving
|
||||
* @param {function(Error=, boolean=): void} callback callback with true when resolveResults resolve the same way
|
||||
* @param {function((Error | null)=, boolean=): void} callback callback with true when resolveResults resolve the same way
|
||||
* @returns {void}
|
||||
*/
|
||||
checkResolveResultsValid(resolveResults, callback) {
|
||||
|
@ -1872,21 +1880,21 @@ class FileSystemInfo {
|
|||
* @param {Object} options options object (for future extensions)
|
||||
* @param {boolean=} options.hash should use hash to snapshot
|
||||
* @param {boolean=} options.timestamp should use timestamp to snapshot
|
||||
* @param {function(WebpackError=, Snapshot=): void} callback callback function
|
||||
* @param {function((WebpackError | null)=, (Snapshot | null)=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
createSnapshot(startTime, files, directories, missing, options, callback) {
|
||||
/** @type {Map<string, FileSystemInfoEntry>} */
|
||||
/** @type {Map<string, FileSystemInfoEntry | null>} */
|
||||
const fileTimestamps = new Map();
|
||||
/** @type {Map<string, string>} */
|
||||
/** @type {Map<string, string | null>} */
|
||||
const fileHashes = new Map();
|
||||
/** @type {Map<string, TimestampAndHash | string>} */
|
||||
/** @type {Map<string, TimestampAndHash | string | null>} */
|
||||
const fileTshs = new Map();
|
||||
/** @type {Map<string, FileSystemInfoEntry>} */
|
||||
/** @type {Map<string, FileSystemInfoEntry | null>} */
|
||||
const contextTimestamps = new Map();
|
||||
/** @type {Map<string, string>} */
|
||||
/** @type {Map<string, string | null>} */
|
||||
const contextHashes = new Map();
|
||||
/** @type {Map<string, TimestampAndHash | string>} */
|
||||
/** @type {Map<string, ResolvedContextTimestampAndHash | null>} */
|
||||
const contextTshs = new Map();
|
||||
/** @type {Map<string, boolean>} */
|
||||
const missingExistence = new Map();
|
||||
|
@ -1966,12 +1974,29 @@ class FileSystemInfo {
|
|||
}
|
||||
};
|
||||
const checkManaged = (path, managedSet) => {
|
||||
for (const immutablePath of this.immutablePathsRegExps) {
|
||||
if (immutablePath.test(path)) {
|
||||
managedSet.add(path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (const immutablePath of this.immutablePathsWithSlash) {
|
||||
if (path.startsWith(immutablePath)) {
|
||||
managedSet.add(path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (const managedPath of this.managedPathsRegExps) {
|
||||
const match = managedPath.exec(path);
|
||||
if (match) {
|
||||
const managedItem = getManagedItem(match[1], path);
|
||||
if (managedItem) {
|
||||
managedItems.add(managedItem);
|
||||
managedSet.add(path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const managedPath of this.managedPathsWithSlash) {
|
||||
if (path.startsWith(managedPath)) {
|
||||
const managedItem = getManagedItem(managedPath, path);
|
||||
|
@ -1991,8 +2016,7 @@ class FileSystemInfo {
|
|||
}
|
||||
return capturedItems;
|
||||
};
|
||||
if (files) {
|
||||
const capturedFiles = captureNonManaged(files, managedFiles);
|
||||
const processCapturedFiles = capturedFiles => {
|
||||
switch (mode) {
|
||||
case 3:
|
||||
this._fileTshsOptimization.optimize(snapshot, capturedFiles);
|
||||
|
@ -2069,17 +2093,17 @@ class FileSystemInfo {
|
|||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
if (files) {
|
||||
processCapturedFiles(captureNonManaged(files, managedFiles));
|
||||
}
|
||||
if (directories) {
|
||||
const capturedDirectories = captureNonManaged(
|
||||
directories,
|
||||
managedContexts
|
||||
);
|
||||
const processCapturedDirectories = capturedDirectories => {
|
||||
switch (mode) {
|
||||
case 3:
|
||||
this._contextTshsOptimization.optimize(snapshot, capturedDirectories);
|
||||
for (const path of capturedDirectories) {
|
||||
const cache = this._contextTshs.get(path);
|
||||
/** @type {ResolvedContextTimestampAndHash} */
|
||||
let resolved;
|
||||
if (
|
||||
cache !== undefined &&
|
||||
|
@ -2088,6 +2112,11 @@ class FileSystemInfo {
|
|||
contextTshs.set(path, resolved);
|
||||
} else {
|
||||
jobs++;
|
||||
/**
|
||||
* @param {Error=} err error
|
||||
* @param {ResolvedContextTimestampAndHash=} entry entry
|
||||
* @returns {void}
|
||||
*/
|
||||
const callback = (err, entry) => {
|
||||
if (err) {
|
||||
if (this.logger) {
|
||||
|
@ -2152,14 +2181,20 @@ class FileSystemInfo {
|
|||
);
|
||||
for (const path of capturedDirectories) {
|
||||
const cache = this._contextTimestamps.get(path);
|
||||
if (cache === "ignore") continue;
|
||||
let resolved;
|
||||
if (
|
||||
cache !== undefined &&
|
||||
(resolved = getResolvedTimestamp(cache)) !== undefined
|
||||
) {
|
||||
contextTimestamps.set(path, resolved);
|
||||
} else if (cache !== "ignore") {
|
||||
} else {
|
||||
jobs++;
|
||||
/**
|
||||
* @param {Error=} err error
|
||||
* @param {ResolvedContextFileSystemInfoEntry=} entry entry
|
||||
* @returns {void}
|
||||
*/
|
||||
const callback = (err, entry) => {
|
||||
if (err) {
|
||||
if (this.logger) {
|
||||
|
@ -2182,9 +2217,13 @@ class FileSystemInfo {
|
|||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
if (directories) {
|
||||
processCapturedDirectories(
|
||||
captureNonManaged(directories, managedContexts)
|
||||
);
|
||||
}
|
||||
if (missing) {
|
||||
const capturedMissing = captureNonManaged(missing, managedMissing);
|
||||
const processCapturedMissing = capturedMissing => {
|
||||
this._missingExistenceOptimization.optimize(snapshot, capturedMissing);
|
||||
for (const path of capturedMissing) {
|
||||
const cache = this._fileTimestamps.get(path);
|
||||
|
@ -2209,11 +2248,19 @@ class FileSystemInfo {
|
|||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
if (missing) {
|
||||
processCapturedMissing(captureNonManaged(missing, managedMissing));
|
||||
}
|
||||
this._managedItemInfoOptimization.optimize(snapshot, managedItems);
|
||||
for (const path of managedItems) {
|
||||
const cache = this._managedItems.get(path);
|
||||
if (cache !== undefined) {
|
||||
if (!cache.startsWith("*")) {
|
||||
managedFiles.add(join(this.fs, path, "package.json"));
|
||||
} else if (cache === "*nested") {
|
||||
managedMissing.add(join(this.fs, path, "package.json"));
|
||||
}
|
||||
managedItemInfo.set(path, cache);
|
||||
} else {
|
||||
jobs++;
|
||||
|
@ -2225,9 +2272,28 @@ class FileSystemInfo {
|
|||
);
|
||||
}
|
||||
jobError();
|
||||
} else {
|
||||
} else if (entry) {
|
||||
if (!entry.startsWith("*")) {
|
||||
managedFiles.add(join(this.fs, path, "package.json"));
|
||||
} else if (cache === "*nested") {
|
||||
managedMissing.add(join(this.fs, path, "package.json"));
|
||||
}
|
||||
managedItemInfo.set(path, entry);
|
||||
jobDone();
|
||||
} else {
|
||||
// Fallback to normal snapshotting
|
||||
const process = (set, fn) => {
|
||||
if (set.size === 0) return;
|
||||
const captured = new Set();
|
||||
for (const file of set) {
|
||||
if (file.startsWith(path)) captured.add(file);
|
||||
}
|
||||
if (captured.size > 0) fn(captured);
|
||||
};
|
||||
process(managedFiles, processCapturedFiles);
|
||||
process(managedContexts, processCapturedDirectories);
|
||||
process(managedMissing, processCapturedMissing);
|
||||
jobDone();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -2313,7 +2379,7 @@ class FileSystemInfo {
|
|||
|
||||
/**
|
||||
* @param {Snapshot} snapshot the snapshot made
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
checkSnapshotValid(snapshot, callback) {
|
||||
|
@ -2333,7 +2399,7 @@ class FileSystemInfo {
|
|||
|
||||
/**
|
||||
* @param {Snapshot} snapshot the snapshot made
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
_checkSnapshotValidNoCache(snapshot, callback) {
|
||||
|
@ -2572,14 +2638,14 @@ class FileSystemInfo {
|
|||
const cache = this._fileTimestamps.get(path);
|
||||
if (cache !== undefined) {
|
||||
if (cache === "ignore" || !checkFile(path, cache, tsh, false)) {
|
||||
processFileHashSnapshot(path, tsh.hash);
|
||||
processFileHashSnapshot(path, tsh && tsh.hash);
|
||||
}
|
||||
} else {
|
||||
jobs++;
|
||||
this.fileTimestampQueue.add(path, (err, entry) => {
|
||||
if (err) return invalidWithError(path, err);
|
||||
if (!checkFile(path, entry, tsh, false)) {
|
||||
processFileHashSnapshot(path, tsh.hash);
|
||||
processFileHashSnapshot(path, tsh && tsh.hash);
|
||||
}
|
||||
jobDone();
|
||||
});
|
||||
|
@ -2592,6 +2658,7 @@ class FileSystemInfo {
|
|||
this._statTestedEntries += contextTimestamps.size;
|
||||
for (const [path, ts] of contextTimestamps) {
|
||||
const cache = this._contextTimestamps.get(path);
|
||||
if (cache === "ignore") continue;
|
||||
let resolved;
|
||||
if (
|
||||
cache !== undefined &&
|
||||
|
@ -2601,8 +2668,13 @@ class FileSystemInfo {
|
|||
invalid();
|
||||
return;
|
||||
}
|
||||
} else if (cache !== "ignore") {
|
||||
} else {
|
||||
jobs++;
|
||||
/**
|
||||
* @param {Error=} err error
|
||||
* @param {ResolvedContextFileSystemInfoEntry=} entry entry
|
||||
* @returns {void}
|
||||
*/
|
||||
const callback = (err, entry) => {
|
||||
if (err) return invalidWithError(path, err);
|
||||
if (!checkContext(path, entry, ts)) {
|
||||
|
@ -2662,27 +2734,33 @@ class FileSystemInfo {
|
|||
processContextHashSnapshot(path, tsh);
|
||||
} else {
|
||||
const cache = this._contextTimestamps.get(path);
|
||||
if (cache === "ignore") continue;
|
||||
let resolved;
|
||||
if (
|
||||
cache !== undefined &&
|
||||
(resolved = getResolvedTimestamp(cache)) !== undefined
|
||||
) {
|
||||
if (!checkContext(path, resolved, tsh, false)) {
|
||||
processContextHashSnapshot(path, tsh.hash);
|
||||
processContextHashSnapshot(path, tsh && tsh.hash);
|
||||
}
|
||||
} else if (cache !== "ignore") {
|
||||
} else {
|
||||
jobs++;
|
||||
/**
|
||||
* @param {Error=} err error
|
||||
* @param {ResolvedContextFileSystemInfoEntry=} entry entry
|
||||
* @returns {void}
|
||||
*/
|
||||
const callback = (err, entry) => {
|
||||
if (err) return invalidWithError(path, err);
|
||||
if (!checkContext(path, entry, tsh, false)) {
|
||||
processContextHashSnapshot(path, tsh.hash);
|
||||
processContextHashSnapshot(path, tsh && tsh.hash);
|
||||
}
|
||||
jobDone();
|
||||
};
|
||||
if (cache !== undefined) {
|
||||
this._resolveContextTsh(cache, callback);
|
||||
this._resolveContextTimestamp(cache, callback);
|
||||
} else {
|
||||
this.getContextTsh(path, callback);
|
||||
this.getContextTimestamp(path, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2870,7 +2948,7 @@ class FileSystemInfo {
|
|||
* @param {function(string, IStats, function(Error=, ItemType=): void): void} options.fromFile called when context item is a file
|
||||
* @param {function(string, IStats, function(Error=, ItemType=): void): void} options.fromDirectory called when context item is a directory
|
||||
* @param {function(string[], ItemType[]): T} options.reduce called from all context items
|
||||
* @param {function(Error=, (T)=): void} callback callback
|
||||
* @param {function((Error | null)=, (T)=): void} callback callback
|
||||
*/
|
||||
_readContext(
|
||||
{
|
||||
|
@ -2899,10 +2977,29 @@ class FileSystemInfo {
|
|||
files,
|
||||
(file, callback) => {
|
||||
const child = join(this.fs, path, file);
|
||||
for (const immutablePath of this.immutablePathsRegExps) {
|
||||
if (immutablePath.test(path)) {
|
||||
// ignore any immutable path for timestamping
|
||||
return callback(null, fromImmutablePath(path));
|
||||
}
|
||||
}
|
||||
for (const immutablePath of this.immutablePathsWithSlash) {
|
||||
if (path.startsWith(immutablePath)) {
|
||||
// ignore any immutable path for timestamping
|
||||
return callback(null, fromImmutablePath(immutablePath));
|
||||
return callback(null, fromImmutablePath(path));
|
||||
}
|
||||
}
|
||||
for (const managedPath of this.managedPathsRegExps) {
|
||||
const match = managedPath.exec(path);
|
||||
if (match) {
|
||||
const managedItem = getManagedItem(match[1], path);
|
||||
if (managedItem) {
|
||||
// construct timestampHash from managed info
|
||||
return this.managedItemQueue.add(managedItem, (err, info) => {
|
||||
if (err) return callback(err);
|
||||
return callback(null, fromManagedItem(info));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const managedPath of this.managedPathsWithSlash) {
|
||||
|
@ -3032,6 +3129,11 @@ class FileSystemInfo {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ContextFileSystemInfoEntry} entry entry
|
||||
* @param {function((Error | null)=, ResolvedContextFileSystemInfoEntry=): void} callback callback
|
||||
* @returns {void}
|
||||
*/
|
||||
_resolveContextTimestamp(entry, callback) {
|
||||
const hashes = [];
|
||||
let safeTime = 0;
|
||||
|
@ -3135,6 +3237,11 @@ class FileSystemInfo {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ContextHash} entry context hash
|
||||
* @param {function((Error | null)=, string=): void} callback callback
|
||||
* @returns {void}
|
||||
*/
|
||||
_resolveContextHash(entry, callback) {
|
||||
const hashes = [];
|
||||
processAsyncTree(
|
||||
|
@ -3286,6 +3393,11 @@ class FileSystemInfo {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ContextTimestampAndHash} entry entry
|
||||
* @param {function((Error | null)=, ResolvedContextTimestampAndHash=): void} callback callback
|
||||
* @returns {void}
|
||||
*/
|
||||
_resolveContextTsh(entry, callback) {
|
||||
const hashes = [];
|
||||
const tsHashes = [];
|
||||
|
@ -3363,8 +3475,8 @@ class FileSystemInfo {
|
|||
}
|
||||
if (!elements.has(path)) {
|
||||
// file or directory doesn't exist
|
||||
this._managedItems.set(path, "missing");
|
||||
return callback(null, "missing");
|
||||
this._managedItems.set(path, "*missing");
|
||||
return callback(null, "*missing");
|
||||
}
|
||||
// something exists
|
||||
// it may be a file or directory
|
||||
|
@ -3373,8 +3485,8 @@ class FileSystemInfo {
|
|||
(path.endsWith("/node_modules") || path.endsWith("\\node_modules"))
|
||||
) {
|
||||
// we are only interested in existence of this special directory
|
||||
this._managedItems.set(path, "exists");
|
||||
return callback(null, "exists");
|
||||
this._managedItems.set(path, "*node_modules");
|
||||
return callback(null, "*node_modules");
|
||||
}
|
||||
|
||||
// we assume it's a directory, as files shouldn't occur in managed paths
|
||||
|
@ -3391,12 +3503,13 @@ class FileSystemInfo {
|
|||
) {
|
||||
// This is only a grouping folder e. g. used by yarn
|
||||
// we are only interested in existence of this special directory
|
||||
this._managedItems.set(path, "nested");
|
||||
return callback(null, "nested");
|
||||
this._managedItems.set(path, "*nested");
|
||||
return callback(null, "*nested");
|
||||
}
|
||||
const problem = `Managed item ${path} isn't a directory or doesn't contain a package.json`;
|
||||
this.logger.warn(problem);
|
||||
return callback(new Error(problem));
|
||||
this.logger.warn(
|
||||
`Managed item ${path} isn't a directory or doesn't contain a package.json (see snapshot.managedPaths option)`
|
||||
);
|
||||
return callback();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -3408,6 +3521,12 @@ class FileSystemInfo {
|
|||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
if (!data.name) {
|
||||
this.logger.warn(
|
||||
`${packageJsonPath} doesn't contain a "name" property (see snapshot.managedPaths option)`
|
||||
);
|
||||
return callback();
|
||||
}
|
||||
const info = `${data.name || ""}@${data.version || ""}`;
|
||||
this._managedItems.set(path, info);
|
||||
callback(null, info);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
||||
/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
|
||||
/** @typedef {import("./Compilation")} Compilation */
|
||||
/** @typedef {import("./ConcatenationScope")} ConcatenationScope */
|
||||
/** @typedef {import("./DependencyTemplate")} DependencyTemplate */
|
||||
|
@ -27,6 +28,7 @@
|
|||
* @property {Set<string>} runtimeRequirements the requirements for runtime
|
||||
* @property {RuntimeSpec} runtime the runtime
|
||||
* @property {ConcatenationScope=} concatenationScope when in concatenated module, information about other concatenated modules
|
||||
* @property {CodeGenerationResults=} codeGenerationResults code generation results of other modules (need to have a codeGenerationDependency to use that)
|
||||
* @property {string} type which kind of code should be generated
|
||||
* @property {function(): Map<string, any>=} getData get access to the code generation data
|
||||
*/
|
||||
|
|
|
@ -51,7 +51,7 @@ module.exports.makeWebpackError = makeWebpackError;
|
|||
|
||||
/**
|
||||
* @template T
|
||||
* @param {function(WebpackError=, T=): void} callback webpack error callback
|
||||
* @param {function((WebpackError | null)=, T=): void} callback webpack error callback
|
||||
* @param {string} hook name of hook
|
||||
* @returns {Callback<T>} generic callback
|
||||
*/
|
||||
|
|
|
@ -83,6 +83,7 @@ class HotModuleReplacementPlugin {
|
|||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
const { _backCompat: backCompat } = compiler;
|
||||
if (compiler.options.output.strictModuleErrorHandling === undefined)
|
||||
compiler.options.output.strictModuleErrorHandling = true;
|
||||
const runtimeRequirements = [RuntimeGlobals.module];
|
||||
|
@ -597,7 +598,8 @@ class HotModuleReplacementPlugin {
|
|||
(newRuntimeModules && newRuntimeModules.length > 0)
|
||||
) {
|
||||
const hotUpdateChunk = new HotUpdateChunk();
|
||||
ChunkGraph.setChunkGraphForChunk(hotUpdateChunk, chunkGraph);
|
||||
if (backCompat)
|
||||
ChunkGraph.setChunkGraphForChunk(hotUpdateChunk, chunkGraph);
|
||||
hotUpdateChunk.id = chunkId;
|
||||
hotUpdateChunk.runtime = newRuntime;
|
||||
if (currentChunk) {
|
||||
|
|
|
@ -19,6 +19,7 @@ const makeSerializable = require("./util/makeSerializable");
|
|||
/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
|
||||
/** @typedef {import("./Chunk")} Chunk */
|
||||
/** @typedef {import("./ChunkGroup")} ChunkGroup */
|
||||
/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
|
||||
/** @typedef {import("./Compilation")} Compilation */
|
||||
/** @typedef {import("./ConcatenationScope")} ConcatenationScope */
|
||||
/** @typedef {import("./Dependency")} Dependency */
|
||||
|
@ -56,6 +57,7 @@ const makeSerializable = require("./util/makeSerializable");
|
|||
* @property {ChunkGraph} chunkGraph the chunk graph
|
||||
* @property {RuntimeSpec} runtime the runtimes code should be generated for
|
||||
* @property {ConcatenationScope=} concatenationScope when in concatenated module, information about other concatenated modules
|
||||
* @property {CodeGenerationResults} codeGenerationResults code generation results of other modules (need to have a codeGenerationDependency to use that)
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -165,6 +167,8 @@ class Module extends DependenciesBlock {
|
|||
this.buildInfo = undefined;
|
||||
/** @type {Dependency[] | undefined} */
|
||||
this.presentationalDependencies = undefined;
|
||||
/** @type {Dependency[] | undefined} */
|
||||
this.codeGenerationDependencies = undefined;
|
||||
}
|
||||
|
||||
// TODO remove in webpack 6
|
||||
|
@ -493,6 +497,19 @@ class Module extends DependenciesBlock {
|
|||
this.presentationalDependencies.push(presentationalDependency);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Dependency} codeGenerationDependency dependency being tied to module.
|
||||
* This is a Dependency where the code generation result of the referenced module is needed during code generation.
|
||||
* The Dependency should also be added to normal dependencies via addDependency.
|
||||
* @returns {void}
|
||||
*/
|
||||
addCodeGenerationDependency(codeGenerationDependency) {
|
||||
if (this.codeGenerationDependencies === undefined) {
|
||||
this.codeGenerationDependencies = [];
|
||||
}
|
||||
this.codeGenerationDependencies.push(codeGenerationDependency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all dependencies and blocks
|
||||
* @returns {void}
|
||||
|
@ -501,6 +518,9 @@ class Module extends DependenciesBlock {
|
|||
if (this.presentationalDependencies !== undefined) {
|
||||
this.presentationalDependencies.length = 0;
|
||||
}
|
||||
if (this.codeGenerationDependencies !== undefined) {
|
||||
this.codeGenerationDependencies.length = 0;
|
||||
}
|
||||
super.clearDependenciesAndBlocks();
|
||||
}
|
||||
|
||||
|
@ -671,7 +691,7 @@ class Module extends DependenciesBlock {
|
|||
|
||||
/**
|
||||
* @param {NeedBuildContext} context context info
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @returns {void}
|
||||
*/
|
||||
needBuild(context, callback) {
|
||||
|
@ -799,7 +819,8 @@ class Module extends DependenciesBlock {
|
|||
runtimeTemplate,
|
||||
moduleGraph: chunkGraph.moduleGraph,
|
||||
chunkGraph,
|
||||
runtime: undefined
|
||||
runtime: undefined,
|
||||
codeGenerationResults: undefined
|
||||
};
|
||||
const sources = this.codeGeneration(codeGenContext).sources;
|
||||
return type ? sources.get(type) : sources.get(first(this.getSourceTypes()));
|
||||
|
@ -976,6 +997,7 @@ class Module extends DependenciesBlock {
|
|||
write(this.buildMeta);
|
||||
write(this.buildInfo);
|
||||
write(this.presentationalDependencies);
|
||||
write(this.codeGenerationDependencies);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
|
@ -993,6 +1015,7 @@ class Module extends DependenciesBlock {
|
|||
this.buildMeta = read();
|
||||
this.buildInfo = read();
|
||||
this.presentationalDependencies = read();
|
||||
this.codeGenerationDependencies = read();
|
||||
super.deserialize(context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const NormalModule = require("./NormalModule");
|
||||
const createHash = require("./util/createHash");
|
||||
const memoize = require("./util/memoize");
|
||||
|
||||
|
@ -138,7 +139,10 @@ ModuleFilenameHelpers.createFilename = (
|
|||
);
|
||||
identifier = memoize(() => requestShortener.shorten(module.identifier()));
|
||||
moduleId = () => chunkGraph.getModuleId(module);
|
||||
absoluteResourcePath = () => module.identifier().split("!").pop();
|
||||
absoluteResourcePath = () =>
|
||||
module instanceof NormalModule
|
||||
? module.resource
|
||||
: module.identifier().split("!").pop();
|
||||
hash = getHash(identifier, hashFunction);
|
||||
}
|
||||
const resource = memoize(() => shortIdentifier().split("!").pop());
|
||||
|
|
|
@ -27,7 +27,7 @@ const ArrayQueue = require("./util/ArrayQueue");
|
|||
/**
|
||||
* @template T
|
||||
* @callback Callback
|
||||
* @param {Error=} err
|
||||
* @param {(Error | null)=} err
|
||||
* @param {T=} result
|
||||
*/
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ const asyncLib = require("neo-async");
|
|||
/**
|
||||
* @template T
|
||||
* @callback Callback
|
||||
* @param {Error=} err
|
||||
* @param {(Error | null)=} err
|
||||
* @param {T=} result
|
||||
*/
|
||||
|
||||
|
|
|
@ -187,6 +187,8 @@ makeSerializable(
|
|||
* @typedef {Object} NormalModuleCompilationHooks
|
||||
* @property {SyncHook<[object, NormalModule]>} loader
|
||||
* @property {SyncHook<[LoaderItem[], NormalModule, object]>} beforeLoaders
|
||||
* @property {SyncHook<[NormalModule]>} beforeParse
|
||||
* @property {SyncHook<[NormalModule]>} beforeSnapshot
|
||||
* @property {HookMap<AsyncSeriesBailHook<[string, NormalModule], string | Buffer>>} readResourceForScheme
|
||||
* @property {HookMap<AsyncSeriesBailHook<[object], string | Buffer>>} readResource
|
||||
* @property {AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>} needBuild
|
||||
|
@ -211,6 +213,8 @@ class NormalModule extends Module {
|
|||
hooks = {
|
||||
loader: new SyncHook(["loaderContext", "module"]),
|
||||
beforeLoaders: new SyncHook(["loaders", "module", "loaderContext"]),
|
||||
beforeParse: new SyncHook(["module"]),
|
||||
beforeSnapshot: new SyncHook(["module"]),
|
||||
// TODO webpack 6 deprecate
|
||||
readResourceForScheme: new HookMap(scheme => {
|
||||
const hook = hooks.readResource.for(scheme);
|
||||
|
@ -306,7 +310,7 @@ class NormalModule extends Module {
|
|||
}
|
||||
|
||||
// Info from Build
|
||||
/** @type {WebpackError=} */
|
||||
/** @type {(WebpackError | null)=} */
|
||||
this.error = null;
|
||||
/** @private @type {Source=} */
|
||||
this._source = null;
|
||||
|
@ -351,11 +355,13 @@ class NormalModule extends Module {
|
|||
* @returns {string | null} an identifier for library inclusion
|
||||
*/
|
||||
libIdent(options) {
|
||||
return contextify(
|
||||
let ident = contextify(
|
||||
options.context,
|
||||
this.userRequest,
|
||||
options.associatedObjectForCache
|
||||
);
|
||||
if (this.layer) ident = `(${this.layer})/${ident}`;
|
||||
return ident;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -387,6 +393,7 @@ class NormalModule extends Module {
|
|||
this.generator = m.generator;
|
||||
this.generatorOptions = m.generatorOptions;
|
||||
this.resource = m.resource;
|
||||
this.resourceResolveData = m.resourceResolveData;
|
||||
this.context = m.context;
|
||||
this.matchResource = m.matchResource;
|
||||
this.loaders = m.loaders;
|
||||
|
@ -488,9 +495,10 @@ class NormalModule extends Module {
|
|||
* @param {WebpackOptions} options webpack options
|
||||
* @param {Compilation} compilation the compilation
|
||||
* @param {InputFileSystem} fs file system from reading
|
||||
* @param {NormalModuleCompilationHooks} hooks the hooks
|
||||
* @returns {NormalModuleLoaderContext} loader context
|
||||
*/
|
||||
createLoaderContext(resolver, options, compilation, fs) {
|
||||
_createLoaderContext(resolver, options, compilation, fs, hooks) {
|
||||
const { requestShortener } = compilation.runtimeTemplate;
|
||||
const getCurrentLoaderName = () => {
|
||||
const currentLoader = this.getCurrentLoader(loaderContext);
|
||||
|
@ -532,6 +540,9 @@ class NormalModule extends Module {
|
|||
return context === this.context
|
||||
? getContextifyInContext()(request)
|
||||
: getContextify()(context, request);
|
||||
},
|
||||
createHash: type => {
|
||||
return createHash(type || compilation.outputOptions.hashFunction);
|
||||
}
|
||||
};
|
||||
const loaderContext = {
|
||||
|
@ -659,10 +670,7 @@ class NormalModule extends Module {
|
|||
|
||||
Object.assign(loaderContext, options.loader);
|
||||
|
||||
NormalModule.getCompilationHooks(compilation).loader.call(
|
||||
loaderContext,
|
||||
this
|
||||
);
|
||||
hooks.loader.call(loaderContext, this);
|
||||
|
||||
return loaderContext;
|
||||
}
|
||||
|
@ -723,15 +731,17 @@ class NormalModule extends Module {
|
|||
* @param {Compilation} compilation the compilation
|
||||
* @param {ResolverWithOptions} resolver the resolver
|
||||
* @param {InputFileSystem} fs the file system
|
||||
* @param {function(WebpackError=): void} callback callback function
|
||||
* @param {NormalModuleCompilationHooks} hooks the hooks
|
||||
* @param {function((WebpackError | null)=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
doBuild(options, compilation, resolver, fs, callback) {
|
||||
const loaderContext = this.createLoaderContext(
|
||||
_doBuild(options, compilation, resolver, fs, hooks, callback) {
|
||||
const loaderContext = this._createLoaderContext(
|
||||
resolver,
|
||||
options,
|
||||
compilation,
|
||||
fs
|
||||
fs,
|
||||
hooks
|
||||
);
|
||||
|
||||
const processResult = (err, result) => {
|
||||
|
@ -785,21 +795,22 @@ class NormalModule extends Module {
|
|||
return callback();
|
||||
};
|
||||
|
||||
const hooks = NormalModule.getCompilationHooks(compilation);
|
||||
|
||||
this.buildInfo.fileDependencies = new LazySet();
|
||||
this.buildInfo.contextDependencies = new LazySet();
|
||||
this.buildInfo.missingDependencies = new LazySet();
|
||||
if (this.loaders.length > 0) {
|
||||
this.buildInfo.buildDependencies = new LazySet();
|
||||
}
|
||||
this.buildInfo.cacheable = true;
|
||||
|
||||
try {
|
||||
hooks.beforeLoaders.call(this.loaders, this, loaderContext);
|
||||
} catch (err) {
|
||||
processResult(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.loaders.length > 0) {
|
||||
this.buildInfo.buildDependencies = new LazySet();
|
||||
}
|
||||
|
||||
runLoaders(
|
||||
{
|
||||
resource: this.resource,
|
||||
|
@ -942,7 +953,9 @@ class NormalModule extends Module {
|
|||
|
||||
const startTime = compilation.compiler.fsStartTime || Date.now();
|
||||
|
||||
return this.doBuild(options, compilation, resolver, fs, err => {
|
||||
const hooks = NormalModule.getCompilationHooks(compilation);
|
||||
|
||||
return this._doBuild(options, compilation, resolver, fs, hooks, err => {
|
||||
// if we have an error mark module as failed and exit
|
||||
if (err) {
|
||||
this.markModuleAsErrored(err);
|
||||
|
@ -974,6 +987,13 @@ class NormalModule extends Module {
|
|||
};
|
||||
|
||||
const handleBuildDone = () => {
|
||||
try {
|
||||
hooks.beforeSnapshot.call(this);
|
||||
} catch (err) {
|
||||
this.markModuleAsErrored(err);
|
||||
return callback();
|
||||
}
|
||||
|
||||
const snapshotOptions = compilation.options.snapshot.module;
|
||||
if (!this.buildInfo.cacheable || !snapshotOptions) {
|
||||
return callback();
|
||||
|
@ -1038,6 +1058,14 @@ class NormalModule extends Module {
|
|||
);
|
||||
};
|
||||
|
||||
try {
|
||||
hooks.beforeParse.call(this);
|
||||
} catch (err) {
|
||||
this.markModuleAsErrored(err);
|
||||
this._initBuildHash(compilation);
|
||||
return callback();
|
||||
}
|
||||
|
||||
// check if this module should !not! be parsed.
|
||||
// if so, exit here;
|
||||
const noParseRule = options.module && options.module.noParse;
|
||||
|
@ -1142,7 +1170,8 @@ class NormalModule extends Module {
|
|||
moduleGraph,
|
||||
chunkGraph,
|
||||
runtime,
|
||||
concatenationScope
|
||||
concatenationScope,
|
||||
codeGenerationResults
|
||||
}) {
|
||||
/** @type {Set<string>} */
|
||||
const runtimeRequirements = new Set();
|
||||
|
@ -1174,6 +1203,7 @@ class NormalModule extends Module {
|
|||
runtimeRequirements,
|
||||
runtime,
|
||||
concatenationScope,
|
||||
codeGenerationResults,
|
||||
getData,
|
||||
type
|
||||
});
|
||||
|
@ -1208,7 +1238,7 @@ class NormalModule extends Module {
|
|||
|
||||
/**
|
||||
* @param {NeedBuildContext} context context info
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @returns {void}
|
||||
*/
|
||||
needBuild(context, callback) {
|
||||
|
|
|
@ -74,7 +74,7 @@ class RawModule extends Module {
|
|||
|
||||
/**
|
||||
* @param {NeedBuildContext} context context info
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @returns {void}
|
||||
*/
|
||||
needBuild(context, callback) {
|
||||
|
|
|
@ -164,7 +164,7 @@ exports.scriptNonce = "__webpack_require__.nc";
|
|||
* function to load a script tag.
|
||||
* Arguments: (url: string, done: (event) => void), key?: string | number, chunkId?: string | number) => void
|
||||
* done function is called when loading has finished or timeout occurred.
|
||||
* It will attach to existing script tags with data-webpack == key or src == url.
|
||||
* It will attach to existing script tags with data-webpack == uniqueName + ":" + key or src == url.
|
||||
*/
|
||||
exports.loadScript = "__webpack_require__.l";
|
||||
|
||||
|
@ -190,11 +190,26 @@ exports.runtimeId = "__webpack_require__.j";
|
|||
*/
|
||||
exports.getChunkScriptFilename = "__webpack_require__.u";
|
||||
|
||||
/**
|
||||
* the filename of the css part of the chunk
|
||||
*/
|
||||
exports.getChunkCssFilename = "__webpack_require__.k";
|
||||
|
||||
/**
|
||||
* a flag when a module/chunk/tree has css modules
|
||||
*/
|
||||
exports.hasCssModules = "has css modules";
|
||||
|
||||
/**
|
||||
* the filename of the script part of the hot update chunk
|
||||
*/
|
||||
exports.getChunkUpdateScriptFilename = "__webpack_require__.hu";
|
||||
|
||||
/**
|
||||
* the filename of the css part of the hot update chunk
|
||||
*/
|
||||
exports.getChunkUpdateCssFilename = "__webpack_require__.hk";
|
||||
|
||||
/**
|
||||
* startup signal from runtime
|
||||
* This will be called when the runtime chunk has been loaded.
|
||||
|
|
|
@ -78,7 +78,7 @@ class RuntimeModule extends Module {
|
|||
|
||||
/**
|
||||
* @param {NeedBuildContext} context context info
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @returns {void}
|
||||
*/
|
||||
needBuild(context, callback) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"use strict";
|
||||
|
||||
const RuntimeGlobals = require("./RuntimeGlobals");
|
||||
const { getChunkFilenameTemplate } = require("./css/CssModulesPlugin");
|
||||
const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirementsDependency");
|
||||
const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
|
||||
const AsyncModuleRuntimeModule = require("./runtime/AsyncModuleRuntimeModule");
|
||||
|
@ -218,7 +219,15 @@ class RuntimePlugin {
|
|||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.systemContext)
|
||||
.tap("RuntimePlugin", chunk => {
|
||||
if (compilation.outputOptions.library.type === "system") {
|
||||
const { outputOptions } = compilation;
|
||||
const { library: globalLibrary } = outputOptions;
|
||||
const entryOptions = chunk.getEntryOptions();
|
||||
const libraryType =
|
||||
entryOptions && entryOptions.library !== undefined
|
||||
? entryOptions.library.type
|
||||
: globalLibrary.type;
|
||||
|
||||
if (libraryType === "system") {
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new SystemContextRuntimeModule()
|
||||
|
@ -253,6 +262,30 @@ class RuntimePlugin {
|
|||
);
|
||||
return true;
|
||||
});
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.getChunkCssFilename)
|
||||
.tap("RuntimePlugin", (chunk, set) => {
|
||||
if (
|
||||
typeof compilation.outputOptions.cssChunkFilename === "string" &&
|
||||
/\[(full)?hash(:\d+)?\]/.test(
|
||||
compilation.outputOptions.cssChunkFilename
|
||||
)
|
||||
) {
|
||||
set.add(RuntimeGlobals.getFullHash);
|
||||
}
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new GetChunkFilenameRuntimeModule(
|
||||
"css",
|
||||
"css",
|
||||
RuntimeGlobals.getChunkCssFilename,
|
||||
chunk =>
|
||||
getChunkFilenameTemplate(chunk, compilation.outputOptions),
|
||||
set.has(RuntimeGlobals.hmrDownloadUpdateHandlers)
|
||||
)
|
||||
);
|
||||
return true;
|
||||
});
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.getChunkUpdateScriptFilename)
|
||||
.tap("RuntimePlugin", (chunk, set) => {
|
||||
|
|
|
@ -16,6 +16,7 @@ const { forEachRuntime, subtractRuntime } = require("./util/runtime");
|
|||
/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */
|
||||
/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
|
||||
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
||||
/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
|
||||
/** @typedef {import("./Compilation")} Compilation */
|
||||
/** @typedef {import("./Dependency")} Dependency */
|
||||
/** @typedef {import("./Module")} Module */
|
||||
|
@ -50,6 +51,27 @@ Module has these incoming connections: ${Array.from(
|
|||
).join("")}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string|undefined} definition global object definition
|
||||
* @returns {string} save to use global object
|
||||
*/
|
||||
function getGlobalObject(definition) {
|
||||
if (!definition) return definition;
|
||||
const trimmed = definition.trim();
|
||||
|
||||
if (
|
||||
// identifier, we do not need real identifier regarding ECMAScript/Unicode
|
||||
trimmed.match(/^[_\p{L}][_0-9\p{L}]*$/iu) ||
|
||||
// iife
|
||||
// call expression
|
||||
// expression in parentheses
|
||||
trimmed.match(/^([_\p{L}][_0-9\p{L}]*)?\(.*\)$/iu)
|
||||
)
|
||||
return trimmed;
|
||||
|
||||
return `Object(${trimmed})`;
|
||||
}
|
||||
|
||||
class RuntimeTemplate {
|
||||
/**
|
||||
* @param {Compilation} compilation the compilation
|
||||
|
@ -60,6 +82,7 @@ class RuntimeTemplate {
|
|||
this.compilation = compilation;
|
||||
this.outputOptions = outputOptions || {};
|
||||
this.requestShortener = requestShortener;
|
||||
this.globalObject = getGlobalObject(outputOptions.globalObject);
|
||||
}
|
||||
|
||||
isIIFE() {
|
||||
|
@ -78,6 +101,10 @@ class RuntimeTemplate {
|
|||
return this.outputOptions.environment.arrowFunction;
|
||||
}
|
||||
|
||||
supportsOptionalChaining() {
|
||||
return this.outputOptions.environment.optionalChaining;
|
||||
}
|
||||
|
||||
supportsForOf() {
|
||||
return this.outputOptions.environment.forOf;
|
||||
}
|
||||
|
@ -99,8 +126,7 @@ class RuntimeTemplate {
|
|||
}
|
||||
|
||||
supportTemplateLiteral() {
|
||||
// TODO
|
||||
return false;
|
||||
return this.outputOptions.environment.templateLiteral;
|
||||
}
|
||||
|
||||
returningFunction(returnValue, args = "") {
|
||||
|
@ -115,6 +141,71 @@ class RuntimeTemplate {
|
|||
: `function(${args}) {\n${Template.indent(body)}\n}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array<string|{expr: string}>} args args
|
||||
* @returns {string} result expression
|
||||
*/
|
||||
concatenation(...args) {
|
||||
const len = args.length;
|
||||
|
||||
if (len === 2) return this._es5Concatenation(args);
|
||||
if (len === 0) return '""';
|
||||
if (len === 1) {
|
||||
return typeof args[0] === "string"
|
||||
? JSON.stringify(args[0])
|
||||
: `"" + ${args[0].expr}`;
|
||||
}
|
||||
if (!this.supportTemplateLiteral()) return this._es5Concatenation(args);
|
||||
|
||||
// cost comparison between template literal and concatenation:
|
||||
// both need equal surroundings: `xxx` vs "xxx"
|
||||
// template literal has constant cost of 3 chars for each expression
|
||||
// es5 concatenation has cost of 3 + n chars for n expressions in row
|
||||
// when a es5 concatenation ends with an expression it reduces cost by 3
|
||||
// when a es5 concatenation starts with an single expression it reduces cost by 3
|
||||
// e. g. `${a}${b}${c}` (3*3 = 9) is longer than ""+a+b+c ((3+3)-3 = 3)
|
||||
// e. g. `x${a}x${b}x${c}x` (3*3 = 9) is shorter than "x"+a+"x"+b+"x"+c+"x" (4+4+4 = 12)
|
||||
|
||||
let templateCost = 0;
|
||||
let concatenationCost = 0;
|
||||
|
||||
let lastWasExpr = false;
|
||||
for (const arg of args) {
|
||||
const isExpr = typeof arg !== "string";
|
||||
if (isExpr) {
|
||||
templateCost += 3;
|
||||
concatenationCost += lastWasExpr ? 1 : 4;
|
||||
}
|
||||
lastWasExpr = isExpr;
|
||||
}
|
||||
if (lastWasExpr) concatenationCost -= 3;
|
||||
if (typeof args[0] !== "string" && typeof args[1] === "string")
|
||||
concatenationCost -= 3;
|
||||
|
||||
if (concatenationCost <= templateCost) return this._es5Concatenation(args);
|
||||
|
||||
return `\`${args
|
||||
.map(arg => (typeof arg === "string" ? arg : `\${${arg.expr}}`))
|
||||
.join("")}\``;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array<string|{expr: string}>} args args (len >= 2)
|
||||
* @returns {string} result expression
|
||||
* @private
|
||||
*/
|
||||
_es5Concatenation(args) {
|
||||
const str = args
|
||||
.map(arg => (typeof arg === "string" ? JSON.stringify(arg) : arg.expr))
|
||||
.join(" + ");
|
||||
|
||||
// when the first two args are expression, we need to prepend "" + to force string
|
||||
// concatenation instead of number addition.
|
||||
return typeof args[0] !== "string" && typeof args[1] !== "string"
|
||||
? `"" + ${str}`
|
||||
: str;
|
||||
}
|
||||
|
||||
expressionFunction(expression, args = "") {
|
||||
return this.supportsArrowFunction()
|
||||
? `(${args}) => (${expression})`
|
||||
|
@ -807,7 +898,7 @@ class RuntimeTemplate {
|
|||
? `(0,${access})`
|
||||
: asiSafe === false
|
||||
? `;(0,${access})`
|
||||
: `Object(${access})`;
|
||||
: `/*#__PURE__*/Object(${access})`;
|
||||
}
|
||||
return access;
|
||||
} else {
|
||||
|
@ -924,6 +1015,26 @@ class RuntimeTemplate {
|
|||
runtimeRequirements.add(RuntimeGlobals.exports);
|
||||
return `${RuntimeGlobals.makeNamespaceObject}(${exportsArgument});\n`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} options options object
|
||||
* @param {Module} options.module the module
|
||||
* @param {string} options.publicPath the public path
|
||||
* @param {RuntimeSpec=} options.runtime runtime
|
||||
* @param {CodeGenerationResults} options.codeGenerationResults the code generation results
|
||||
* @returns {string} the url of the asset
|
||||
*/
|
||||
assetUrl({ publicPath, runtime, module, codeGenerationResults }) {
|
||||
if (!module) {
|
||||
return "data:,";
|
||||
}
|
||||
const codeGen = codeGenerationResults.get(module, runtime);
|
||||
const { data } = codeGen;
|
||||
const url = data.get("url");
|
||||
if (url) return url;
|
||||
const filename = data.get("filename");
|
||||
return publicPath + filename;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RuntimeTemplate;
|
||||
|
|
|
@ -370,7 +370,8 @@ class Template {
|
|||
dependencyTemplates: renderContext.dependencyTemplates,
|
||||
moduleGraph: renderContext.moduleGraph,
|
||||
runtimeTemplate: renderContext.runtimeTemplate,
|
||||
runtime: renderContext.chunk.runtime
|
||||
runtime: renderContext.chunk.runtime,
|
||||
codeGenerationResults
|
||||
});
|
||||
if (!codeGenResult) continue;
|
||||
runtimeSource = codeGenResult.sources.get("runtime");
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { groupBy } = require("./util/ArrayHelpers");
|
||||
const createSchemaValidation = require("./util/create-schema-validation");
|
||||
|
||||
/** @typedef {import("../declarations/plugins/WatchIgnorePlugin").WatchIgnorePluginOptions} WatchIgnorePluginOptions */
|
||||
|
@ -40,14 +41,12 @@ class IgnoringWatchFileSystem {
|
|||
p instanceof RegExp ? p.test(path) : path.indexOf(p) === 0
|
||||
);
|
||||
|
||||
const notIgnored = path => !ignored(path);
|
||||
|
||||
const ignoredFiles = files.filter(ignored);
|
||||
const ignoredDirs = dirs.filter(ignored);
|
||||
const [ignoredFiles, notIgnoredFiles] = groupBy(files, ignored);
|
||||
const [ignoredDirs, notIgnoredDirs] = groupBy(dirs, ignored);
|
||||
|
||||
const watcher = this.wfs.watch(
|
||||
files.filter(notIgnored),
|
||||
dirs.filter(notIgnored),
|
||||
notIgnoredFiles,
|
||||
notIgnoredDirs,
|
||||
missing,
|
||||
startTime,
|
||||
options,
|
||||
|
@ -88,7 +87,20 @@ class IgnoringWatchFileSystem {
|
|||
fileTimestamps.set(path, IGNORE_TIME_ENTRY);
|
||||
}
|
||||
return fileTimestamps;
|
||||
}
|
||||
},
|
||||
getInfo:
|
||||
watcher.getInfo &&
|
||||
(() => {
|
||||
const info = watcher.getInfo();
|
||||
const { fileTimeInfoEntries, contextTimeInfoEntries } = info;
|
||||
for (const path of ignoredFiles) {
|
||||
fileTimeInfoEntries.set(path, IGNORE_TIME_ENTRY);
|
||||
}
|
||||
for (const path of ignoredDirs) {
|
||||
contextTimeInfoEntries.set(path, IGNORE_TIME_ENTRY);
|
||||
}
|
||||
return info;
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ const Stats = require("./Stats");
|
|||
/**
|
||||
* @template T
|
||||
* @callback Callback
|
||||
* @param {Error=} err
|
||||
* @param {(Error | null)=} err
|
||||
* @param {T=} result
|
||||
*/
|
||||
|
||||
|
@ -49,7 +49,7 @@ class Watching {
|
|||
this.watchOptions = {};
|
||||
}
|
||||
if (typeof this.watchOptions.aggregateTimeout !== "number") {
|
||||
this.watchOptions.aggregateTimeout = 200;
|
||||
this.watchOptions.aggregateTimeout = 20;
|
||||
}
|
||||
this.compiler = compiler;
|
||||
this.running = false;
|
||||
|
@ -109,30 +109,44 @@ class Watching {
|
|||
this.lastWatcherStartTime = Date.now();
|
||||
}
|
||||
this.compiler.fsStartTime = Date.now();
|
||||
this._mergeWithCollected(
|
||||
changedFiles ||
|
||||
(this.pausedWatcher &&
|
||||
if (
|
||||
changedFiles &&
|
||||
removedFiles &&
|
||||
fileTimeInfoEntries &&
|
||||
contextTimeInfoEntries
|
||||
) {
|
||||
this._mergeWithCollected(changedFiles, removedFiles);
|
||||
this.compiler.fileTimestamps = fileTimeInfoEntries;
|
||||
this.compiler.contextTimestamps = contextTimeInfoEntries;
|
||||
} else if (this.pausedWatcher) {
|
||||
if (this.pausedWatcher.getInfo) {
|
||||
const {
|
||||
changes,
|
||||
removals,
|
||||
fileTimeInfoEntries,
|
||||
contextTimeInfoEntries
|
||||
} = this.pausedWatcher.getInfo();
|
||||
this._mergeWithCollected(changes, removals);
|
||||
this.compiler.fileTimestamps = fileTimeInfoEntries;
|
||||
this.compiler.contextTimestamps = contextTimeInfoEntries;
|
||||
} else {
|
||||
this._mergeWithCollected(
|
||||
this.pausedWatcher.getAggregatedChanges &&
|
||||
this.pausedWatcher.getAggregatedChanges()),
|
||||
(this.compiler.removedFiles =
|
||||
removedFiles ||
|
||||
(this.pausedWatcher &&
|
||||
this.pausedWatcher.getAggregatedChanges(),
|
||||
this.pausedWatcher.getAggregatedRemovals &&
|
||||
this.pausedWatcher.getAggregatedRemovals()))
|
||||
);
|
||||
|
||||
this.pausedWatcher.getAggregatedRemovals()
|
||||
);
|
||||
this.compiler.fileTimestamps =
|
||||
this.pausedWatcher.getFileTimeInfoEntries();
|
||||
this.compiler.contextTimestamps =
|
||||
this.pausedWatcher.getContextTimeInfoEntries();
|
||||
}
|
||||
}
|
||||
this.compiler.modifiedFiles = this._collectedChangedFiles;
|
||||
this._collectedChangedFiles = undefined;
|
||||
this.compiler.removedFiles = this._collectedRemovedFiles;
|
||||
this._collectedRemovedFiles = undefined;
|
||||
|
||||
this.compiler.fileTimestamps =
|
||||
fileTimeInfoEntries ||
|
||||
(this.pausedWatcher && this.pausedWatcher.getFileTimeInfoEntries());
|
||||
this.compiler.contextTimestamps =
|
||||
contextTimeInfoEntries ||
|
||||
(this.pausedWatcher && this.pausedWatcher.getContextTimeInfoEntries());
|
||||
|
||||
const run = () => {
|
||||
if (this.compiler.idle) {
|
||||
return this.compiler.cache.endIdle(err => {
|
||||
|
|
|
@ -118,11 +118,47 @@ class WebpackOptionsApply extends OptionsApply {
|
|||
if (options.externalsPresets.webAsync) {
|
||||
//@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
|
||||
const ExternalsPlugin = require("./ExternalsPlugin");
|
||||
new ExternalsPlugin("import", /^(https?:\/\/|std:)/).apply(compiler);
|
||||
new ExternalsPlugin(
|
||||
"import",
|
||||
options.experiments.css
|
||||
? ({ request, dependencyType }, callback) => {
|
||||
if (dependencyType === "url") {
|
||||
if (/^(\/\/|https?:\/\/)/.test(request))
|
||||
return callback(null, `asset ${request}`);
|
||||
} else if (dependencyType === "css-import") {
|
||||
if (/^(\/\/|https?:\/\/)/.test(request))
|
||||
return callback(null, `css-import ${request}`);
|
||||
} else if (/^(\/\/|https?:\/\/|std:)/.test(request)) {
|
||||
if (/^\.css(\?|$)/.test(request))
|
||||
return callback(null, `css-import ${request}`);
|
||||
return callback(null, `import ${request}`);
|
||||
}
|
||||
callback();
|
||||
}
|
||||
: /^(\/\/|https?:\/\/|std:)/
|
||||
).apply(compiler);
|
||||
} else if (options.externalsPresets.web) {
|
||||
//@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
|
||||
const ExternalsPlugin = require("./ExternalsPlugin");
|
||||
new ExternalsPlugin("module", /^(https?:\/\/|std:)/).apply(compiler);
|
||||
new ExternalsPlugin(
|
||||
"module",
|
||||
options.experiments.css
|
||||
? ({ request, dependencyType }, callback) => {
|
||||
if (dependencyType === "url") {
|
||||
if (/^(\/\/|https?:\/\/)/.test(request))
|
||||
return callback(null, `asset ${request}`);
|
||||
} else if (dependencyType === "css-import") {
|
||||
if (/^(\/\/|https?:\/\/)/.test(request))
|
||||
return callback(null, `css-import ${request}`);
|
||||
} else if (/^(\/\/|https?:\/\/|std:)/.test(request)) {
|
||||
if (/^\.css(\?|$)/.test(request))
|
||||
return callback(null, `css-import ${request}`);
|
||||
return callback(null, `module ${request}`);
|
||||
}
|
||||
callback();
|
||||
}
|
||||
: /^(\/\/|https?:\/\/|std:)/
|
||||
).apply(compiler);
|
||||
}
|
||||
|
||||
new ChunkPrefetchPreloadPlugin().apply(compiler);
|
||||
|
@ -253,6 +289,11 @@ class WebpackOptionsApply extends OptionsApply {
|
|||
}).apply(compiler);
|
||||
}
|
||||
|
||||
if (options.experiments.css) {
|
||||
const CssModulesPlugin = require("./css/CssModulesPlugin");
|
||||
new CssModulesPlugin().apply(compiler);
|
||||
}
|
||||
|
||||
if (options.experiments.lazyCompilation) {
|
||||
const LazyCompilationPlugin = require("./hmr/LazyCompilationPlugin");
|
||||
const lazyOptions =
|
||||
|
@ -261,15 +302,18 @@ class WebpackOptionsApply extends OptionsApply {
|
|||
: null;
|
||||
new LazyCompilationPlugin({
|
||||
backend:
|
||||
(lazyOptions && lazyOptions.backend) ||
|
||||
require("./hmr/lazyCompilationBackend"),
|
||||
client:
|
||||
(lazyOptions && lazyOptions.client) ||
|
||||
require.resolve(
|
||||
`../hot/lazy-compilation-${
|
||||
options.externalsPresets.node ? "node" : "web"
|
||||
}.js`
|
||||
),
|
||||
typeof lazyOptions.backend === "function"
|
||||
? lazyOptions.backend
|
||||
: require("./hmr/lazyCompilationBackend")({
|
||||
...lazyOptions.backend,
|
||||
client:
|
||||
(lazyOptions.backend && lazyOptions.backend.client) ||
|
||||
require.resolve(
|
||||
`../hot/lazy-compilation-${
|
||||
options.externalsPresets.node ? "node" : "web"
|
||||
}.js`
|
||||
)
|
||||
}),
|
||||
entries: !lazyOptions || lazyOptions.entries !== false,
|
||||
imports: !lazyOptions || lazyOptions.imports !== false,
|
||||
test: (lazyOptions && lazyOptions.test) || undefined
|
||||
|
@ -279,8 +323,6 @@ class WebpackOptionsApply extends OptionsApply {
|
|||
if (options.experiments.buildHttp) {
|
||||
const HttpUriPlugin = require("./schemes/HttpUriPlugin");
|
||||
const httpOptions = options.experiments.buildHttp;
|
||||
if (httpOptions === true)
|
||||
throw new Error("Unexpected due to normalization");
|
||||
new HttpUriPlugin(httpOptions).apply(compiler);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ const { makePathsRelative } = require("../util/identifier");
|
|||
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").AssetGeneratorOptions} AssetGeneratorOptions */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").AssetModuleOutputPath} AssetModuleOutputPath */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").RawPublicPath} RawPublicPath */
|
||||
/** @typedef {import("../Compilation")} Compilation */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
|
@ -49,7 +50,7 @@ const mergeAssetInfo = (a, b) => {
|
|||
case "immutable":
|
||||
case "development":
|
||||
case "hotModuleReplacement":
|
||||
case "javascriptModule ":
|
||||
case "javascriptModule":
|
||||
result[key] = a[key] || b[key];
|
||||
break;
|
||||
case "related":
|
||||
|
@ -74,6 +75,41 @@ const mergeRelatedInfo = (a, b) => {
|
|||
return result;
|
||||
};
|
||||
|
||||
const encodeDataUri = (encoding, source) => {
|
||||
let encodedContent;
|
||||
|
||||
switch (encoding) {
|
||||
case "base64": {
|
||||
encodedContent = source.buffer().toString("base64");
|
||||
break;
|
||||
}
|
||||
case false: {
|
||||
const content = source.source();
|
||||
|
||||
if (typeof content !== "string") {
|
||||
encodedContent = content.toString("utf-8");
|
||||
}
|
||||
|
||||
encodedContent = encodeURIComponent(encodedContent).replace(
|
||||
/[!'()*]/g,
|
||||
character => "%" + character.codePointAt(0).toString(16)
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported encoding '${encoding}'`);
|
||||
}
|
||||
|
||||
return encodedContent;
|
||||
};
|
||||
|
||||
const decodeDataUriContent = (encoding, content) => {
|
||||
const isBase64 = encoding === "base64";
|
||||
return isBase64
|
||||
? Buffer.from(content, "base64")
|
||||
: Buffer.from(decodeURIComponent(content), "ascii");
|
||||
};
|
||||
|
||||
const JS_TYPES = new Set(["javascript"]);
|
||||
const JS_AND_ASSET_TYPES = new Set(["javascript", "asset"]);
|
||||
|
||||
|
@ -82,13 +118,15 @@ class AssetGenerator extends Generator {
|
|||
* @param {AssetGeneratorOptions["dataUrl"]=} dataUrlOptions the options for the data url
|
||||
* @param {string=} filename override for output.assetModuleFilename
|
||||
* @param {RawPublicPath=} publicPath override for output.assetModulePublicPath
|
||||
* @param {AssetModuleOutputPath=} outputPath the output path for the emitted file which is not included in the runtime import
|
||||
* @param {boolean=} emit generate output asset
|
||||
*/
|
||||
constructor(dataUrlOptions, filename, publicPath, emit) {
|
||||
constructor(dataUrlOptions, filename, publicPath, outputPath, emit) {
|
||||
super();
|
||||
this.dataUrlOptions = dataUrlOptions;
|
||||
this.filename = filename;
|
||||
this.publicPath = publicPath;
|
||||
this.outputPath = outputPath;
|
||||
this.emit = emit;
|
||||
}
|
||||
|
||||
|
@ -158,39 +196,26 @@ class AssetGenerator extends Generator {
|
|||
}
|
||||
|
||||
let encodedContent;
|
||||
|
||||
if (
|
||||
module.resourceResolveData &&
|
||||
module.resourceResolveData.encoding === encoding
|
||||
module.resourceResolveData.encoding === encoding &&
|
||||
decodeDataUriContent(
|
||||
module.resourceResolveData.encoding,
|
||||
module.resourceResolveData.encodedContent
|
||||
).equals(originalSource.buffer())
|
||||
) {
|
||||
encodedContent = module.resourceResolveData.encodedContent;
|
||||
} else {
|
||||
switch (encoding) {
|
||||
case "base64": {
|
||||
encodedContent = originalSource.buffer().toString("base64");
|
||||
break;
|
||||
}
|
||||
case false: {
|
||||
const content = originalSource.source();
|
||||
|
||||
if (typeof content !== "string") {
|
||||
encodedContent = content.toString("utf-8");
|
||||
}
|
||||
|
||||
encodedContent = encodeURIComponent(encodedContent).replace(
|
||||
/[!'()*]/g,
|
||||
character => "%" + character.codePointAt(0).toString(16)
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported encoding '${encoding}'`);
|
||||
}
|
||||
encodedContent = encodeDataUri(encoding, originalSource);
|
||||
}
|
||||
|
||||
encodedSource = `data:${mimeType}${
|
||||
encoding ? `;${encoding}` : ""
|
||||
},${encodedContent}`;
|
||||
}
|
||||
const data = getData();
|
||||
data.set("url", encodedSource);
|
||||
return new RawSource(
|
||||
`${RuntimeGlobals.module}.exports = ${JSON.stringify(
|
||||
encodedSource
|
||||
|
@ -228,7 +253,7 @@ class AssetGenerator extends Generator {
|
|||
contentHash
|
||||
}
|
||||
);
|
||||
let publicPath;
|
||||
let assetPath;
|
||||
if (this.publicPath !== undefined) {
|
||||
const { path, info } =
|
||||
runtimeTemplate.compilation.getAssetPathWithInfo(
|
||||
|
@ -241,16 +266,34 @@ class AssetGenerator extends Generator {
|
|||
contentHash
|
||||
}
|
||||
);
|
||||
publicPath = JSON.stringify(path);
|
||||
assetInfo = mergeAssetInfo(assetInfo, info);
|
||||
assetPath = JSON.stringify(path + filename);
|
||||
} else {
|
||||
publicPath = RuntimeGlobals.publicPath;
|
||||
runtimeRequirements.add(RuntimeGlobals.publicPath); // add __webpack_require__.p
|
||||
assetPath = runtimeTemplate.concatenation(
|
||||
{ expr: RuntimeGlobals.publicPath },
|
||||
filename
|
||||
);
|
||||
}
|
||||
assetInfo = {
|
||||
sourceFilename,
|
||||
...assetInfo
|
||||
};
|
||||
if (this.outputPath) {
|
||||
const { path: outputPath, info } =
|
||||
runtimeTemplate.compilation.getAssetPathWithInfo(
|
||||
this.outputPath,
|
||||
{
|
||||
module,
|
||||
runtime,
|
||||
filename: sourceFilename,
|
||||
chunkGraph,
|
||||
contentHash
|
||||
}
|
||||
);
|
||||
assetInfo = mergeAssetInfo(assetInfo, info);
|
||||
filename = path.posix.join(outputPath, filename);
|
||||
}
|
||||
module.buildInfo.filename = filename;
|
||||
module.buildInfo.assetInfo = assetInfo;
|
||||
if (getData) {
|
||||
|
@ -264,9 +307,7 @@ class AssetGenerator extends Generator {
|
|||
}
|
||||
|
||||
return new RawSource(
|
||||
`${
|
||||
RuntimeGlobals.module
|
||||
}.exports = ${publicPath} + ${JSON.stringify(filename)};`
|
||||
`${RuntimeGlobals.module}.exports = ${assetPath};`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,9 +137,11 @@ class AssetModulesPlugin {
|
|||
|
||||
let filename = undefined;
|
||||
let publicPath = undefined;
|
||||
let outputPath = undefined;
|
||||
if (type !== "asset/inline") {
|
||||
filename = generatorOptions.filename;
|
||||
publicPath = generatorOptions.publicPath;
|
||||
outputPath = generatorOptions.outputPath;
|
||||
}
|
||||
|
||||
const AssetGenerator = getAssetGenerator();
|
||||
|
@ -148,6 +150,7 @@ class AssetModulesPlugin {
|
|||
dataUrl,
|
||||
filename,
|
||||
publicPath,
|
||||
outputPath,
|
||||
generatorOptions.emit !== false
|
||||
);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { RawSource } = require("webpack-sources");
|
||||
const Module = require("../Module");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
|
||||
/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
|
||||
/** @typedef {import("../Compilation")} Compilation */
|
||||
/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
|
||||
/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
|
||||
/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
|
||||
/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
|
||||
/** @typedef {import("../RequestShortener")} RequestShortener */
|
||||
/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
|
||||
/** @typedef {import("../WebpackError")} WebpackError */
|
||||
/** @typedef {import("../util/Hash")} Hash */
|
||||
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
|
||||
|
||||
const TYPES = new Set(["javascript"]);
|
||||
|
||||
class RawDataUrlModule extends Module {
|
||||
/**
|
||||
* @param {string} url raw url
|
||||
* @param {string} identifier unique identifier
|
||||
* @param {string=} readableIdentifier readable identifier
|
||||
*/
|
||||
constructor(url, identifier, readableIdentifier) {
|
||||
super("asset/raw-data-url", null);
|
||||
this.url = url;
|
||||
this.identifierStr = identifier || this.url;
|
||||
this.readableIdentifierStr = readableIdentifier || this.identifierStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Set<string>} types available (do not mutate)
|
||||
*/
|
||||
getSourceTypes() {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} a unique identifier of the module
|
||||
*/
|
||||
identifier() {
|
||||
return this.identifierStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string=} type the source type for which the size should be estimated
|
||||
* @returns {number} the estimated size of the module (must be non-zero)
|
||||
*/
|
||||
size(type) {
|
||||
return Math.max(1, this.url.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {RequestShortener} requestShortener the request shortener
|
||||
* @returns {string} a user readable identifier of the module
|
||||
*/
|
||||
readableIdentifier(requestShortener) {
|
||||
return requestShortener.shorten(this.readableIdentifierStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NeedBuildContext} context context info
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @returns {void}
|
||||
*/
|
||||
needBuild(context, callback) {
|
||||
return callback(null, !this.buildMeta);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {WebpackOptions} options webpack options
|
||||
* @param {Compilation} compilation the compilation
|
||||
* @param {ResolverWithOptions} resolver the resolver
|
||||
* @param {InputFileSystem} fs the file system
|
||||
* @param {function(WebpackError=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
build(options, compilation, resolver, fs, callback) {
|
||||
this.buildMeta = {};
|
||||
this.buildInfo = {
|
||||
cacheable: true
|
||||
};
|
||||
callback();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CodeGenerationContext} context context for code generation
|
||||
* @returns {CodeGenerationResult} result
|
||||
*/
|
||||
codeGeneration(context) {
|
||||
const sources = new Map();
|
||||
sources.set(
|
||||
"javascript",
|
||||
new RawSource(`module.exports = ${JSON.stringify(this.url)};`)
|
||||
);
|
||||
const data = new Map();
|
||||
data.set("url", this.url);
|
||||
const runtimeRequirements = new Set();
|
||||
runtimeRequirements.add(RuntimeGlobals.module);
|
||||
return { sources, runtimeRequirements, data };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Hash} hash the hash used to track dependencies
|
||||
* @param {UpdateHashContext} context context
|
||||
* @returns {void}
|
||||
*/
|
||||
updateHash(hash, context) {
|
||||
hash.update(this.url);
|
||||
super.updateHash(hash, context);
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
|
||||
write(this.url);
|
||||
write(this.identifierStr);
|
||||
write(this.readableIdentifierStr);
|
||||
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
deserialize(context) {
|
||||
const { read } = context;
|
||||
|
||||
this.url = read();
|
||||
this.identifierStr = read();
|
||||
this.readableIdentifierStr = read();
|
||||
|
||||
super.deserialize(context);
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(RawDataUrlModule, "webpack/lib/asset/RawDataUrlModule");
|
||||
|
||||
module.exports = RawDataUrlModule;
|
|
@ -50,6 +50,8 @@ const { getEntryRuntime, mergeRuntime } = require("./util/runtime");
|
|||
* @property {Set<ChunkGroupInfo>} availableChildren set of chunk groups which depend on the this chunk group as availableSource
|
||||
* @property {number} preOrderIndex next pre order index
|
||||
* @property {number} postOrderIndex next post order index
|
||||
* @property {boolean} chunkLoading has a chunk loading mechanism
|
||||
* @property {boolean} asyncChunks create async chunks
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -304,7 +306,15 @@ const visitModules = (
|
|||
availableSources: undefined,
|
||||
availableChildren: undefined,
|
||||
preOrderIndex: 0,
|
||||
postOrderIndex: 0
|
||||
postOrderIndex: 0,
|
||||
chunkLoading:
|
||||
chunkGroup.options.chunkLoading !== undefined
|
||||
? chunkGroup.options.chunkLoading !== false
|
||||
: compilation.outputOptions.chunkLoading !== false,
|
||||
asyncChunks:
|
||||
chunkGroup.options.asyncChunks !== undefined
|
||||
? chunkGroup.options.asyncChunks
|
||||
: compilation.outputOptions.asyncChunks !== false
|
||||
};
|
||||
chunkGroup.index = nextChunkGroupIndex++;
|
||||
if (chunkGroup.getNumberOfParents() > 0) {
|
||||
|
@ -418,7 +428,15 @@ const visitModules = (
|
|||
availableSources: undefined,
|
||||
availableChildren: undefined,
|
||||
preOrderIndex: 0,
|
||||
postOrderIndex: 0
|
||||
postOrderIndex: 0,
|
||||
chunkLoading:
|
||||
entryOptions.chunkLoading !== undefined
|
||||
? entryOptions.chunkLoading !== false
|
||||
: chunkGroupInfo.chunkLoading,
|
||||
asyncChunks:
|
||||
entryOptions.asyncChunks !== undefined
|
||||
? entryOptions.asyncChunks
|
||||
: chunkGroupInfo.asyncChunks
|
||||
};
|
||||
chunkGroupInfoMap.set(entrypoint, cgi);
|
||||
|
||||
|
@ -442,8 +460,18 @@ const visitModules = (
|
|||
chunkGroup: entrypoint,
|
||||
chunkGroupInfo: cgi
|
||||
});
|
||||
} else if (!chunkGroupInfo.asyncChunks || !chunkGroupInfo.chunkLoading) {
|
||||
// Just queue the block into the current chunk group
|
||||
queue.push({
|
||||
action: PROCESS_BLOCK,
|
||||
block: b,
|
||||
module: module,
|
||||
chunk,
|
||||
chunkGroup,
|
||||
chunkGroupInfo
|
||||
});
|
||||
} else {
|
||||
cgi = namedChunkGroups.get(chunkName);
|
||||
cgi = chunkName && namedChunkGroups.get(chunkName);
|
||||
if (!cgi) {
|
||||
c = compilation.addChunkInGroup(
|
||||
b.groupOptions || b.chunkName,
|
||||
|
@ -464,7 +492,9 @@ const visitModules = (
|
|||
availableSources: undefined,
|
||||
availableChildren: undefined,
|
||||
preOrderIndex: 0,
|
||||
postOrderIndex: 0
|
||||
postOrderIndex: 0,
|
||||
chunkLoading: chunkGroupInfo.chunkLoading,
|
||||
asyncChunks: chunkGroupInfo.asyncChunks
|
||||
};
|
||||
allCreatedChunkGroups.add(c);
|
||||
chunkGroupInfoMap.set(c, cgi);
|
||||
|
@ -518,7 +548,7 @@ const visitModules = (
|
|||
chunkGroup: c,
|
||||
chunkGroupInfo: cgi
|
||||
});
|
||||
} else {
|
||||
} else if (entrypoint !== undefined) {
|
||||
chunkGroupInfo.chunkGroup.addAsyncEntrypoint(entrypoint);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
class AddManagedPathsPlugin {
|
||||
/**
|
||||
* @param {Iterable<string>} managedPaths list of managed paths
|
||||
* @param {Iterable<string>} immutablePaths list of immutable paths
|
||||
* @param {Iterable<string | RegExp>} managedPaths list of managed paths
|
||||
* @param {Iterable<string | RegExp>} immutablePaths list of immutable paths
|
||||
*/
|
||||
constructor(managedPaths, immutablePaths) {
|
||||
this.managedPaths = new Set(managedPaths);
|
||||
|
|
|
@ -370,8 +370,8 @@ class Pack {
|
|||
for (const identifier of content.items) {
|
||||
mergedItems.add(identifier);
|
||||
}
|
||||
for (const identifer of content.used) {
|
||||
mergedUsedItems.add(identifer);
|
||||
for (const identifier of content.used) {
|
||||
mergedUsedItems.add(identifier);
|
||||
}
|
||||
addToMergedMap.push(async map => {
|
||||
// unpack existing content
|
||||
|
@ -782,7 +782,7 @@ class PackContent {
|
|||
this.logger.time(timeMessage);
|
||||
}
|
||||
const value = this.lazy();
|
||||
if (value instanceof Promise) {
|
||||
if ("then" in value) {
|
||||
return value.then(data => {
|
||||
const map = data.map;
|
||||
if (timeMessage) {
|
||||
|
@ -830,7 +830,7 @@ class PackContent {
|
|||
this.logger.time(timeMessage);
|
||||
}
|
||||
const value = this.lazy();
|
||||
if (value instanceof Promise) {
|
||||
if ("then" in value) {
|
||||
return value.then(data => {
|
||||
if (timeMessage) {
|
||||
this.logger.timeEnd(timeMessage);
|
||||
|
@ -918,7 +918,7 @@ class PackContent {
|
|||
}
|
||||
const value = this.lazy();
|
||||
this.outdated = false;
|
||||
if (value instanceof Promise) {
|
||||
if ("then" in value) {
|
||||
// Move to state B1
|
||||
this.lazy = write(() =>
|
||||
value.then(data => {
|
||||
|
@ -991,7 +991,10 @@ class PackFileCacheStrategy {
|
|||
allowCollectingMemory,
|
||||
compression
|
||||
}) {
|
||||
this.fileSerializer = createFileSerializer(fs);
|
||||
this.fileSerializer = createFileSerializer(
|
||||
fs,
|
||||
compiler.options.output.hashFunction
|
||||
);
|
||||
this.fileSystemInfo = new FileSystemInfo(fs, {
|
||||
managedPaths: snapshot.managedPaths,
|
||||
immutablePaths: snapshot.immutablePaths,
|
||||
|
|
|
@ -106,7 +106,7 @@ class ResolverCachePlugin {
|
|||
* @param {Resolver} resolver the resolver
|
||||
* @param {Object} resolveContext context for resolving meta info
|
||||
* @param {Object} request the request info object
|
||||
* @param {function(Error=, Object=): void} callback callback function
|
||||
* @param {function((Error | null)=, Object=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
const doRealResolve = (
|
||||
|
|
47
lib/cli.js
47
lib/cli.js
|
@ -37,6 +37,7 @@ const webpackSchema = require("../schemas/WebpackOptions.json");
|
|||
/**
|
||||
* @typedef {Object} ArgumentConfig
|
||||
* @property {string} description
|
||||
* @property {string} [negatedDescription]
|
||||
* @property {string} path
|
||||
* @property {boolean} multiple
|
||||
* @property {"enum"|"string"|"path"|"number"|"boolean"|"RegExp"|"reset"} type
|
||||
|
@ -96,11 +97,42 @@ const getArguments = (schema = webpackSchema) => {
|
|||
*/
|
||||
const getDescription = path => {
|
||||
for (const { schema } of path) {
|
||||
if (schema.cli && schema.cli.helper) continue;
|
||||
if (schema.cli) {
|
||||
if (schema.cli.helper) continue;
|
||||
if (schema.cli.description) return schema.cli.description;
|
||||
}
|
||||
if (schema.description) return schema.description;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {PathItem[]} path path in the schema
|
||||
* @returns {string | undefined} negative description
|
||||
*/
|
||||
const getNegatedDescription = path => {
|
||||
for (const { schema } of path) {
|
||||
if (schema.cli) {
|
||||
if (schema.cli.helper) continue;
|
||||
if (schema.cli.negatedDescription) return schema.cli.negatedDescription;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {PathItem[]} path path in the schema
|
||||
* @returns {string | undefined} reset description
|
||||
*/
|
||||
const getResetDescription = path => {
|
||||
for (const { schema } of path) {
|
||||
if (schema.cli) {
|
||||
if (schema.cli.helper) continue;
|
||||
if (schema.cli.resetDescription) return schema.cli.resetDescription;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {any} schemaPart schema
|
||||
|
@ -142,13 +174,17 @@ const getArguments = (schema = webpackSchema) => {
|
|||
const addResetFlag = path => {
|
||||
const schemaPath = path[0].path;
|
||||
const name = pathToArgumentName(`${schemaPath}.reset`);
|
||||
const description = getDescription(path);
|
||||
const description =
|
||||
getResetDescription(path) ||
|
||||
`Clear all items provided in '${schemaPath}' configuration. ${getDescription(
|
||||
path
|
||||
)}`;
|
||||
flags[name] = {
|
||||
configs: [
|
||||
{
|
||||
type: "reset",
|
||||
multiple: false,
|
||||
description: `Clear all items provided in '${schemaPath}' configuration. ${description}`,
|
||||
description,
|
||||
path: schemaPath
|
||||
}
|
||||
],
|
||||
|
@ -167,6 +203,7 @@ const getArguments = (schema = webpackSchema) => {
|
|||
const argConfigBase = schemaToArgumentConfig(path[0].schema);
|
||||
if (!argConfigBase) return 0;
|
||||
|
||||
const negatedDescription = getNegatedDescription(path);
|
||||
const name = pathToArgumentName(path[0].path);
|
||||
/** @type {ArgumentConfig} */
|
||||
const argConfig = {
|
||||
|
@ -176,6 +213,10 @@ const getArguments = (schema = webpackSchema) => {
|
|||
path: path[0].path
|
||||
};
|
||||
|
||||
if (negatedDescription) {
|
||||
argConfig.negatedDescription = negatedDescription;
|
||||
}
|
||||
|
||||
if (!flags[name]) {
|
||||
flags[name] = {
|
||||
configs: [],
|
||||
|
|
|
@ -274,7 +274,44 @@ const resolve = browsers => {
|
|||
// kaios: Unknown support
|
||||
node: [12, 0]
|
||||
}),
|
||||
|
||||
optionalChaining: rawChecker({
|
||||
chrome: 80,
|
||||
and_chr: 80,
|
||||
edge: 80,
|
||||
firefox: 74,
|
||||
and_ff: 79,
|
||||
// ie: Not supported,
|
||||
opera: 67,
|
||||
op_mob: 64,
|
||||
safari: [13, 1],
|
||||
ios_saf: [13, 4],
|
||||
samsung: 13,
|
||||
android: 80,
|
||||
// and_qq: Not supported
|
||||
// baidu: Not supported
|
||||
// and_uc: Not supported
|
||||
// kaios: Not supported
|
||||
node: 14
|
||||
}),
|
||||
templateLiteral: rawChecker({
|
||||
chrome: 41,
|
||||
and_chr: 41,
|
||||
edge: 13,
|
||||
firefox: 34,
|
||||
and_ff: 34,
|
||||
// ie: Not supported,
|
||||
opera: 29,
|
||||
op_mob: 64,
|
||||
safari: [9, 1],
|
||||
ios_saf: 9,
|
||||
samsung: 4,
|
||||
android: 41,
|
||||
and_qq: [10, 4],
|
||||
baidu: [7, 12],
|
||||
and_uc: [12, 12],
|
||||
kaios: [2, 5],
|
||||
node: 4
|
||||
}),
|
||||
browser: browserProperty,
|
||||
electron: false,
|
||||
node: nodeProperty,
|
||||
|
|
|
@ -19,6 +19,7 @@ const {
|
|||
/** @typedef {import("../../declarations/WebpackOptions").EntryDescription} EntryDescription */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").EntryNormalized} Entry */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").Experiments} Experiments */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").ExperimentsNormalized} ExperimentsNormalized */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").ExternalsPresets} ExternalsPresets */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").ExternalsType} ExternalsType */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").InfrastructureLogging} InfrastructureLogging */
|
||||
|
@ -161,6 +162,8 @@ const applyWebpackOptionsDefaults = options => {
|
|||
|
||||
applyExperimentsDefaults(options.experiments, { production, development });
|
||||
|
||||
const futureDefaults = options.experiments.futureDefaults;
|
||||
|
||||
F(options, "cache", () =>
|
||||
development ? { type: /** @type {"memory"} */ ("memory") } : false
|
||||
);
|
||||
|
@ -172,12 +175,17 @@ const applyWebpackOptionsDefaults = options => {
|
|||
});
|
||||
const cache = !!options.cache;
|
||||
|
||||
applySnapshotDefaults(options.snapshot, { production });
|
||||
applySnapshotDefaults(options.snapshot, {
|
||||
production,
|
||||
futureDefaults
|
||||
});
|
||||
|
||||
applyModuleDefaults(options.module, {
|
||||
cache,
|
||||
syncWebAssembly: options.experiments.syncWebAssembly,
|
||||
asyncWebAssembly: options.experiments.asyncWebAssembly
|
||||
asyncWebAssembly: options.experiments.asyncWebAssembly,
|
||||
css: options.experiments.css,
|
||||
futureDefaults
|
||||
});
|
||||
|
||||
applyOutputDefaults(options.output, {
|
||||
|
@ -192,7 +200,7 @@ const applyWebpackOptionsDefaults = options => {
|
|||
development,
|
||||
entry: options.entry,
|
||||
module: options.module,
|
||||
futureDefaults: options.experiments.futureDefaults
|
||||
futureDefaults
|
||||
});
|
||||
|
||||
applyExternalsPresetsDefaults(options.externalsPresets, {
|
||||
|
@ -232,6 +240,7 @@ const applyWebpackOptionsDefaults = options => {
|
|||
applyOptimizationDefaults(options.optimization, {
|
||||
development,
|
||||
production,
|
||||
css: options.experiments.css,
|
||||
records: !!(options.recordsInputPath || options.recordsOutputPath)
|
||||
});
|
||||
|
||||
|
@ -252,27 +261,28 @@ const applyWebpackOptionsDefaults = options => {
|
|||
};
|
||||
|
||||
/**
|
||||
* @param {Experiments} experiments options
|
||||
* @param {ExperimentsNormalized} experiments options
|
||||
* @param {Object} options options
|
||||
* @param {boolean} options.production is production
|
||||
* @param {boolean} options.development is development mode
|
||||
* @returns {void}
|
||||
*/
|
||||
const applyExperimentsDefaults = (experiments, { production, development }) => {
|
||||
D(experiments, "topLevelAwait", false);
|
||||
D(experiments, "syncWebAssembly", false);
|
||||
D(experiments, "asyncWebAssembly", false);
|
||||
D(experiments, "outputModule", false);
|
||||
D(experiments, "asset", false);
|
||||
D(experiments, "layers", false);
|
||||
D(experiments, "lazyCompilation", false);
|
||||
D(experiments, "buildHttp", false);
|
||||
D(experiments, "futureDefaults", false);
|
||||
D(experiments, "backCompat", !experiments.futureDefaults);
|
||||
D(experiments, "topLevelAwait", experiments.futureDefaults);
|
||||
D(experiments, "syncWebAssembly", false);
|
||||
D(experiments, "asyncWebAssembly", experiments.futureDefaults);
|
||||
D(experiments, "outputModule", false);
|
||||
D(experiments, "layers", false);
|
||||
D(experiments, "lazyCompilation", undefined);
|
||||
D(experiments, "buildHttp", undefined);
|
||||
D(experiments, "cacheUnaffected", experiments.futureDefaults);
|
||||
D(experiments, "css", experiments.futureDefaults);
|
||||
|
||||
if (typeof experiments.buildHttp === "object") {
|
||||
D(experiments.buildHttp, "frozen", production);
|
||||
D(experiments.buildHttp, "upgrade", development);
|
||||
D(experiments.buildHttp, "upgrade", false);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -348,49 +358,65 @@ const applyCacheDefaults = (
|
|||
* @param {SnapshotOptions} snapshot options
|
||||
* @param {Object} options options
|
||||
* @param {boolean} options.production is production
|
||||
* @param {boolean} options.futureDefaults is future defaults enabled
|
||||
* @returns {void}
|
||||
*/
|
||||
const applySnapshotDefaults = (snapshot, { production }) => {
|
||||
A(snapshot, "managedPaths", () => {
|
||||
if (process.versions.pnp === "3") {
|
||||
const match =
|
||||
/^(.+?)[\\/]cache[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec(
|
||||
const applySnapshotDefaults = (snapshot, { production, futureDefaults }) => {
|
||||
if (futureDefaults) {
|
||||
F(snapshot, "managedPaths", () =>
|
||||
process.versions.pnp === "3"
|
||||
? [
|
||||
/^(.+?(?:[\\/]\.yarn[\\/]unplugged[\\/][^\\/]+)?[\\/]node_modules[\\/])/
|
||||
]
|
||||
: [/^(.+?[\\/]node_modules[\\/])/]
|
||||
);
|
||||
F(snapshot, "immutablePaths", () =>
|
||||
process.versions.pnp === "3"
|
||||
? [/^(.+?[\\/]cache[\\/][^\\/]+\.zip[\\/]node_modules[\\/])/]
|
||||
: []
|
||||
);
|
||||
} else {
|
||||
A(snapshot, "managedPaths", () => {
|
||||
if (process.versions.pnp === "3") {
|
||||
const match =
|
||||
/^(.+?)[\\/]cache[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec(
|
||||
require.resolve("watchpack")
|
||||
);
|
||||
if (match) {
|
||||
return [path.resolve(match[1], "unplugged")];
|
||||
}
|
||||
} else {
|
||||
const match = /^(.+?[\\/]node_modules[\\/])/.exec(
|
||||
// eslint-disable-next-line node/no-extraneous-require
|
||||
require.resolve("watchpack")
|
||||
);
|
||||
if (match) {
|
||||
return [path.resolve(match[1], "unplugged")];
|
||||
if (match) {
|
||||
return [match[1]];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const match = /^(.+?[\\/]node_modules)[\\/]/.exec(
|
||||
// eslint-disable-next-line node/no-extraneous-require
|
||||
require.resolve("watchpack")
|
||||
);
|
||||
if (match) {
|
||||
return [match[1]];
|
||||
return [];
|
||||
});
|
||||
A(snapshot, "immutablePaths", () => {
|
||||
if (process.versions.pnp === "1") {
|
||||
const match =
|
||||
/^(.+?[\\/]v4)[\\/]npm-watchpack-[^\\/]+-[\da-f]{40}[\\/]node_modules[\\/]/.exec(
|
||||
require.resolve("watchpack")
|
||||
);
|
||||
if (match) {
|
||||
return [match[1]];
|
||||
}
|
||||
} else if (process.versions.pnp === "3") {
|
||||
const match =
|
||||
/^(.+?)[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec(
|
||||
require.resolve("watchpack")
|
||||
);
|
||||
if (match) {
|
||||
return [match[1]];
|
||||
}
|
||||
}
|
||||
}
|
||||
return [];
|
||||
});
|
||||
A(snapshot, "immutablePaths", () => {
|
||||
if (process.versions.pnp === "1") {
|
||||
const match =
|
||||
/^(.+?[\\/]v4)[\\/]npm-watchpack-[^\\/]+-[\da-f]{40}[\\/]node_modules[\\/]/.exec(
|
||||
require.resolve("watchpack")
|
||||
);
|
||||
if (match) {
|
||||
return [match[1]];
|
||||
}
|
||||
} else if (process.versions.pnp === "3") {
|
||||
const match =
|
||||
/^(.+?)[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec(
|
||||
require.resolve("watchpack")
|
||||
);
|
||||
if (match) {
|
||||
return [match[1]];
|
||||
}
|
||||
}
|
||||
return [];
|
||||
});
|
||||
return [];
|
||||
});
|
||||
}
|
||||
F(snapshot, "resolveBuildDependencies", () => ({
|
||||
timestamp: true,
|
||||
hash: true
|
||||
|
@ -406,9 +432,14 @@ const applySnapshotDefaults = (snapshot, { production }) => {
|
|||
|
||||
/**
|
||||
* @param {JavascriptParserOptions} parserOptions parser options
|
||||
* @param {Object} options options
|
||||
* @param {boolean} options.futureDefaults is future defaults enabled
|
||||
* @returns {void}
|
||||
*/
|
||||
const applyJavascriptParserOptionsDefaults = parserOptions => {
|
||||
const applyJavascriptParserOptionsDefaults = (
|
||||
parserOptions,
|
||||
{ futureDefaults }
|
||||
) => {
|
||||
D(parserOptions, "unknownContextRequest", ".");
|
||||
D(parserOptions, "unknownContextRegExp", false);
|
||||
D(parserOptions, "unknownContextRecursive", true);
|
||||
|
@ -420,9 +451,8 @@ const applyJavascriptParserOptionsDefaults = parserOptions => {
|
|||
D(parserOptions, "wrappedContextRegExp", /.*/);
|
||||
D(parserOptions, "wrappedContextRecursive", true);
|
||||
D(parserOptions, "wrappedContextCritical", false);
|
||||
|
||||
D(parserOptions, "strictExportPresence", false);
|
||||
D(parserOptions, "strictThisContextOnImports", false);
|
||||
if (futureDefaults) D(parserOptions, "exportsPresence", "error");
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -431,11 +461,13 @@ const applyJavascriptParserOptionsDefaults = parserOptions => {
|
|||
* @param {boolean} options.cache is caching enabled
|
||||
* @param {boolean} options.syncWebAssembly is syncWebAssembly enabled
|
||||
* @param {boolean} options.asyncWebAssembly is asyncWebAssembly enabled
|
||||
* @param {boolean} options.css is css enabled
|
||||
* @param {boolean} options.futureDefaults is future defaults enabled
|
||||
* @returns {void}
|
||||
*/
|
||||
const applyModuleDefaults = (
|
||||
module,
|
||||
{ cache, syncWebAssembly, asyncWebAssembly }
|
||||
{ cache, syncWebAssembly, asyncWebAssembly, css, futureDefaults }
|
||||
) => {
|
||||
if (cache) {
|
||||
D(module, "unsafeCache", module => {
|
||||
|
@ -453,7 +485,9 @@ const applyModuleDefaults = (
|
|||
}
|
||||
|
||||
F(module.parser, "javascript", () => ({}));
|
||||
applyJavascriptParserOptionsDefaults(module.parser.javascript);
|
||||
applyJavascriptParserOptionsDefaults(module.parser.javascript, {
|
||||
futureDefaults
|
||||
});
|
||||
|
||||
A(module, "defaultRules", () => {
|
||||
const esm = {
|
||||
|
@ -557,6 +591,41 @@ const applyModuleDefaults = (
|
|||
...wasm
|
||||
});
|
||||
}
|
||||
if (css) {
|
||||
const cssRule = {
|
||||
type: "css",
|
||||
resolve: {
|
||||
fullySpecified: true,
|
||||
preferRelative: true
|
||||
}
|
||||
};
|
||||
const cssModulesRule = {
|
||||
type: "css/module",
|
||||
resolve: {
|
||||
fullySpecified: true
|
||||
}
|
||||
};
|
||||
rules.push({
|
||||
test: /\.css$/i,
|
||||
oneOf: [
|
||||
{
|
||||
test: /\.module\.css$/i,
|
||||
...cssModulesRule
|
||||
},
|
||||
{
|
||||
...cssRule
|
||||
}
|
||||
]
|
||||
});
|
||||
rules.push({
|
||||
mimetype: "text/css+module",
|
||||
...cssModulesRule
|
||||
});
|
||||
rules.push({
|
||||
mimetype: "text/css",
|
||||
...cssRule
|
||||
});
|
||||
}
|
||||
rules.push(
|
||||
{
|
||||
dependency: "url",
|
||||
|
@ -662,6 +731,20 @@ const applyOutputDefaults = (
|
|||
}
|
||||
return output.module ? "[id].mjs" : "[id].js";
|
||||
});
|
||||
F(output, "cssFilename", () => {
|
||||
const filename = output.filename;
|
||||
if (typeof filename !== "function") {
|
||||
return filename.replace(/\.[mc]?js(\?|$)/, ".css$1");
|
||||
}
|
||||
return "[id].css";
|
||||
});
|
||||
F(output, "cssChunkFilename", () => {
|
||||
const chunkFilename = output.chunkFilename;
|
||||
if (typeof chunkFilename !== "function") {
|
||||
return chunkFilename.replace(/\.[mc]?js(\?|$)/, ".css$1");
|
||||
}
|
||||
return "[id].css";
|
||||
});
|
||||
D(output, "assetModuleFilename", "[hash][ext][query]");
|
||||
D(output, "webassemblyModuleFilename", "[hash].module.wasm");
|
||||
D(output, "compareBeforeEmit", true);
|
||||
|
@ -714,6 +797,7 @@ const applyOutputDefaults = (
|
|||
"Chunk format can't be selected by default when no target is specified"
|
||||
);
|
||||
});
|
||||
D(output, "asyncChunks", true);
|
||||
F(output, "chunkLoading", () => {
|
||||
if (tp) {
|
||||
switch (output.chunkFormat) {
|
||||
|
@ -801,7 +885,7 @@ const applyOutputDefaults = (
|
|||
D(output, "chunkLoadTimeout", 120000);
|
||||
D(output, "hashFunction", futureDefaults ? "xxhash64" : "md4");
|
||||
D(output, "hashDigest", "hex");
|
||||
D(output, "hashDigestLength", 20);
|
||||
D(output, "hashDigestLength", futureDefaults ? 16 : 20);
|
||||
D(output, "strictModuleExceptionHandling", false);
|
||||
|
||||
const optimistic = v => v || v === undefined;
|
||||
|
@ -999,12 +1083,13 @@ const applyPerformanceDefaults = (performance, { production }) => {
|
|||
* @param {Object} options options
|
||||
* @param {boolean} options.production is production
|
||||
* @param {boolean} options.development is development
|
||||
* @param {boolean} options.css is css enabled
|
||||
* @param {boolean} options.records using records
|
||||
* @returns {void}
|
||||
*/
|
||||
const applyOptimizationDefaults = (
|
||||
optimization,
|
||||
{ production, development, records }
|
||||
{ production, development, css, records }
|
||||
) => {
|
||||
D(optimization, "removeAvailableModules", false);
|
||||
D(optimization, "removeEmptyChunks", true);
|
||||
|
@ -1055,7 +1140,9 @@ const applyOptimizationDefaults = (
|
|||
});
|
||||
const { splitChunks } = optimization;
|
||||
if (splitChunks) {
|
||||
A(splitChunks, "defaultSizeTypes", () => ["javascript", "unknown"]);
|
||||
A(splitChunks, "defaultSizeTypes", () =>
|
||||
css ? ["javascript", "css", "unknown"] : ["javascript", "unknown"]
|
||||
);
|
||||
D(splitChunks, "hidePathInfo", production);
|
||||
D(splitChunks, "chunks", "async");
|
||||
D(splitChunks, "usedExports", optimization.usedExports === true);
|
||||
|
|
|
@ -174,7 +174,12 @@ const getNormalizedWebpackOptions = config => {
|
|||
experiments: nestedConfig(config.experiments, experiments => ({
|
||||
...experiments,
|
||||
buildHttp: optionalNestedConfig(experiments.buildHttp, options =>
|
||||
options === true ? {} : options
|
||||
Array.isArray(options) ? { allowedUris: options } : options
|
||||
),
|
||||
lazyCompilation: optionalNestedConfig(
|
||||
experiments.lazyCompilation,
|
||||
options =>
|
||||
options === true ? {} : options === false ? undefined : options
|
||||
)
|
||||
})),
|
||||
externals: config.externals,
|
||||
|
@ -224,6 +229,7 @@ const getNormalizedWebpackOptions = config => {
|
|||
wrappedContextRegExp: module.wrappedContextRegExp,
|
||||
wrappedContextRecursive: module.wrappedContextRecursive,
|
||||
wrappedContextCritical: module.wrappedContextCritical,
|
||||
// TODO webpack 6 remove
|
||||
strictExportPresence: module.strictExportPresence,
|
||||
strictThisContextOnImports: module.strictThisContextOnImports,
|
||||
...parserOptions
|
||||
|
@ -284,12 +290,15 @@ const getNormalizedWebpackOptions = config => {
|
|||
/** @type {OutputNormalized} */
|
||||
const result = {
|
||||
assetModuleFilename: output.assetModuleFilename,
|
||||
asyncChunks: output.asyncChunks,
|
||||
charset: output.charset,
|
||||
chunkFilename: output.chunkFilename,
|
||||
chunkFormat: output.chunkFormat,
|
||||
chunkLoading: output.chunkLoading,
|
||||
chunkLoadingGlobal: output.chunkLoadingGlobal,
|
||||
chunkLoadTimeout: output.chunkLoadTimeout,
|
||||
cssFilename: output.cssFilename,
|
||||
cssChunkFilename: output.cssChunkFilename,
|
||||
clean: output.clean,
|
||||
compareBeforeEmit: output.compareBeforeEmit,
|
||||
crossOriginLoading: output.crossOriginLoading,
|
||||
|
@ -478,6 +487,7 @@ const getNormalizedEntryStatic = entry => {
|
|||
runtime: value.runtime,
|
||||
publicPath: value.publicPath,
|
||||
chunkLoading: value.chunkLoading,
|
||||
asyncChunks: value.asyncChunks,
|
||||
wasmLoading: value.wasmLoading,
|
||||
dependOn:
|
||||
value.dependOn &&
|
||||
|
|
|
@ -59,6 +59,8 @@ const getDefaultTarget = context => {
|
|||
* @property {boolean | null} dynamicImport async import() is available
|
||||
* @property {boolean | null} dynamicImportInWorker async import() is available when creating a worker
|
||||
* @property {boolean | null} module ESM syntax is available (when in module)
|
||||
* @property {boolean | null} optionalChaining optional chaining is available
|
||||
* @property {boolean | null} templateLiteral template literal is available
|
||||
*/
|
||||
|
||||
///** @typedef {PlatformTargetProperties | ApiTargetProperties | EcmaTargetProperties | PlatformTargetProperties & ApiTargetProperties | PlatformTargetProperties & EcmaTargetProperties | ApiTargetProperties & EcmaTargetProperties} TargetProperties */
|
||||
|
@ -167,6 +169,8 @@ You can also more options via the 'target' option: 'browserslist' / 'browserslis
|
|||
|
||||
globalThis: v(12),
|
||||
const: v(6),
|
||||
templateLiteral: v(4),
|
||||
optionalChaining: v(14),
|
||||
arrowFunction: v(6),
|
||||
forOf: v(5),
|
||||
destructuring: v(6),
|
||||
|
@ -206,6 +210,8 @@ You can also more options via the 'target' option: 'browserslist' / 'browserslis
|
|||
|
||||
globalThis: v(5),
|
||||
const: v(1, 1),
|
||||
templateLiteral: v(1, 1),
|
||||
optionalChaining: v(8),
|
||||
arrowFunction: v(1, 1),
|
||||
forOf: v(0, 36),
|
||||
destructuring: v(1, 1),
|
||||
|
@ -241,6 +247,8 @@ You can also more options via the 'target' option: 'browserslist' / 'browserslis
|
|||
|
||||
globalThis: v(0, 43),
|
||||
const: v(0, 15),
|
||||
templateLiteral: v(0, 13),
|
||||
optionalChaining: v(0, 44),
|
||||
arrowFunction: v(0, 15),
|
||||
forOf: v(0, 13),
|
||||
destructuring: v(0, 15),
|
||||
|
@ -260,6 +268,8 @@ You can also more options via the 'target' option: 'browserslist' / 'browserslis
|
|||
if (v < 1000) v = v + 2009;
|
||||
return {
|
||||
const: v >= 2015,
|
||||
templateLiteral: v >= 2015,
|
||||
optionalChaining: v >= 2020,
|
||||
arrowFunction: v >= 2015,
|
||||
forOf: v >= 2015,
|
||||
destructuring: v >= 2015,
|
||||
|
|
|
@ -10,6 +10,7 @@ const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
|
|||
const Module = require("../Module");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const Template = require("../Template");
|
||||
const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const ContainerExposedDependency = require("./ContainerExposedDependency");
|
||||
|
||||
|
@ -78,12 +79,14 @@ class ContainerEntryModule extends Module {
|
|||
* @returns {string | null} an identifier for library inclusion
|
||||
*/
|
||||
libIdent(options) {
|
||||
return `webpack/container/entry/${this._name}`;
|
||||
return `${this.layer ? `(${this.layer})/` : ""}webpack/container/entry/${
|
||||
this._name
|
||||
}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NeedBuildContext} context context info
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @returns {void}
|
||||
*/
|
||||
needBuild(context, callback) {
|
||||
|
@ -104,6 +107,7 @@ class ContainerEntryModule extends Module {
|
|||
strict: true,
|
||||
topLevelDeclarations: new Set(["moduleMap", "get", "init"])
|
||||
};
|
||||
this.buildMeta.exportsType = "namespace";
|
||||
|
||||
this.clearDependenciesAndBlocks();
|
||||
|
||||
|
@ -127,6 +131,7 @@ class ContainerEntryModule extends Module {
|
|||
}
|
||||
this.addBlock(block);
|
||||
}
|
||||
this.addDependency(new StaticExportsDependency(["get", "init"], false));
|
||||
|
||||
callback();
|
||||
}
|
||||
|
@ -217,10 +222,8 @@ class ContainerEntryModule extends Module {
|
|||
])};`,
|
||||
`var init = ${runtimeTemplate.basicFunction("shareScope, initScope", [
|
||||
`if (!${RuntimeGlobals.shareScopeMap}) return;`,
|
||||
`var oldScope = ${RuntimeGlobals.shareScopeMap}[${JSON.stringify(
|
||||
this._shareScope
|
||||
)}];`,
|
||||
`var name = ${JSON.stringify(this._shareScope)}`,
|
||||
`var oldScope = ${RuntimeGlobals.shareScopeMap}[name];`,
|
||||
`if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope");`,
|
||||
`${RuntimeGlobals.shareScopeMap}[name] = shareScope;`,
|
||||
`return ${RuntimeGlobals.initializeSharing}(name, initScope);`
|
||||
|
|
|
@ -60,9 +60,9 @@ class FallbackModule extends Module {
|
|||
* @returns {string | null} an identifier for library inclusion
|
||||
*/
|
||||
libIdent(options) {
|
||||
return `webpack/container/fallback/${this.requests[0]}/and ${
|
||||
this.requests.length - 1
|
||||
} more`;
|
||||
return `${this.layer ? `(${this.layer})/` : ""}webpack/container/fallback/${
|
||||
this.requests[0]
|
||||
}/and ${this.requests.length - 1} more`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,7 +76,7 @@ class FallbackModule extends Module {
|
|||
|
||||
/**
|
||||
* @param {NeedBuildContext} context context info
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @returns {void}
|
||||
*/
|
||||
needBuild(context, callback) {
|
||||
|
|
|
@ -67,12 +67,14 @@ class RemoteModule extends Module {
|
|||
* @returns {string | null} an identifier for library inclusion
|
||||
*/
|
||||
libIdent(options) {
|
||||
return `webpack/container/remote/${this.request}`;
|
||||
return `${this.layer ? `(${this.layer})/` : ""}webpack/container/remote/${
|
||||
this.request
|
||||
}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NeedBuildContext} context context info
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @returns {void}
|
||||
*/
|
||||
needBuild(context, callback) {
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Sergey Melyukov @smelukov
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { ReplaceSource } = require("webpack-sources");
|
||||
const Generator = require("../Generator");
|
||||
const InitFragment = require("../InitFragment");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("../Dependency")} Dependency */
|
||||
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
|
||||
/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
|
||||
/** @typedef {import("../NormalModule")} NormalModule */
|
||||
/** @typedef {import("../util/Hash")} Hash */
|
||||
|
||||
const TYPES = new Set(["css"]);
|
||||
|
||||
class CssGenerator extends Generator {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NormalModule} module module for which the code should be generated
|
||||
* @param {GenerateContext} generateContext context for generate
|
||||
* @returns {Source} generated code
|
||||
*/
|
||||
generate(module, generateContext) {
|
||||
const originalSource = module.originalSource();
|
||||
const source = new ReplaceSource(originalSource);
|
||||
const initFragments = [];
|
||||
const cssExports = new Map();
|
||||
|
||||
generateContext.runtimeRequirements.add(RuntimeGlobals.hasCssModules);
|
||||
|
||||
const templateContext = {
|
||||
runtimeTemplate: generateContext.runtimeTemplate,
|
||||
dependencyTemplates: generateContext.dependencyTemplates,
|
||||
moduleGraph: generateContext.moduleGraph,
|
||||
chunkGraph: generateContext.chunkGraph,
|
||||
module,
|
||||
runtime: generateContext.runtime,
|
||||
runtimeRequirements: generateContext.runtimeRequirements,
|
||||
concatenationScope: generateContext.concatenationScope,
|
||||
codeGenerationResults: generateContext.codeGenerationResults,
|
||||
initFragments,
|
||||
cssExports
|
||||
};
|
||||
|
||||
const handleDependency = dependency => {
|
||||
const constructor = /** @type {new (...args: any[]) => Dependency} */ (
|
||||
dependency.constructor
|
||||
);
|
||||
const template = generateContext.dependencyTemplates.get(constructor);
|
||||
if (!template) {
|
||||
throw new Error(
|
||||
"No template for dependency: " + dependency.constructor.name
|
||||
);
|
||||
}
|
||||
|
||||
template.apply(dependency, source, templateContext);
|
||||
};
|
||||
module.dependencies.forEach(handleDependency);
|
||||
if (module.presentationalDependencies !== undefined)
|
||||
module.presentationalDependencies.forEach(handleDependency);
|
||||
|
||||
if (cssExports.size > 0) {
|
||||
const data = generateContext.getData();
|
||||
data.set("css-exports", cssExports);
|
||||
}
|
||||
|
||||
return InitFragment.addToSource(source, initFragments, generateContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NormalModule} module fresh module
|
||||
* @returns {Set<string>} available types (do not mutate)
|
||||
*/
|
||||
getTypes(module) {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NormalModule} module the module
|
||||
* @param {string=} type source type
|
||||
* @returns {number} estimate size of the module
|
||||
*/
|
||||
getSize(module, type) {
|
||||
const originalSource = module.originalSource();
|
||||
|
||||
if (!originalSource) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return originalSource.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Hash} hash hash that will be modified
|
||||
* @param {UpdateHashContext} updateHashContext context for updating hash
|
||||
*/
|
||||
updateHash(hash, { module }) {}
|
||||
}
|
||||
|
||||
module.exports = CssGenerator;
|
|
@ -0,0 +1,449 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { SyncWaterfallHook } = require("tapable");
|
||||
const Compilation = require("../Compilation");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const RuntimeModule = require("../RuntimeModule");
|
||||
const Template = require("../Template");
|
||||
const compileBooleanMatcher = require("../util/compileBooleanMatcher");
|
||||
const { chunkHasCss } = require("./CssModulesPlugin");
|
||||
|
||||
/** @typedef {import("../Chunk")} Chunk */
|
||||
|
||||
/**
|
||||
* @typedef {Object} JsonpCompilationPluginHooks
|
||||
* @property {SyncWaterfallHook<[string, Chunk]>} createStylesheet
|
||||
*/
|
||||
|
||||
/** @type {WeakMap<Compilation, JsonpCompilationPluginHooks>} */
|
||||
const compilationHooksMap = new WeakMap();
|
||||
|
||||
class CssLoadingRuntimeModule extends RuntimeModule {
|
||||
/**
|
||||
* @param {Compilation} compilation the compilation
|
||||
* @returns {JsonpCompilationPluginHooks} hooks
|
||||
*/
|
||||
static getCompilationHooks(compilation) {
|
||||
if (!(compilation instanceof Compilation)) {
|
||||
throw new TypeError(
|
||||
"The 'compilation' argument must be an instance of Compilation"
|
||||
);
|
||||
}
|
||||
let hooks = compilationHooksMap.get(compilation);
|
||||
if (hooks === undefined) {
|
||||
hooks = {
|
||||
createStylesheet: new SyncWaterfallHook(["source", "chunk"])
|
||||
};
|
||||
compilationHooksMap.set(compilation, hooks);
|
||||
}
|
||||
return hooks;
|
||||
}
|
||||
|
||||
constructor(runtimeRequirements, runtimeOptions) {
|
||||
super("css loading", 10);
|
||||
|
||||
this._runtimeRequirements = runtimeRequirements;
|
||||
this.runtimeOptions = runtimeOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} runtime code
|
||||
*/
|
||||
generate() {
|
||||
const { compilation, chunk, _runtimeRequirements } = this;
|
||||
const {
|
||||
chunkGraph,
|
||||
runtimeTemplate,
|
||||
outputOptions: {
|
||||
crossOriginLoading,
|
||||
uniqueName,
|
||||
chunkLoadTimeout: loadTimeout
|
||||
}
|
||||
} = compilation;
|
||||
const fn = RuntimeGlobals.ensureChunkHandlers;
|
||||
const conditionMap = chunkGraph.getChunkConditionMap(
|
||||
chunk,
|
||||
(chunk, chunkGraph) =>
|
||||
!!chunkGraph.getChunkModulesIterableBySourceType(chunk, "css")
|
||||
);
|
||||
const hasCssMatcher = compileBooleanMatcher(conditionMap);
|
||||
|
||||
const withLoading =
|
||||
_runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) &&
|
||||
hasCssMatcher !== false;
|
||||
const withHmr = _runtimeRequirements.has(
|
||||
RuntimeGlobals.hmrDownloadUpdateHandlers
|
||||
);
|
||||
const initialChunkIdsWithCss = new Set();
|
||||
const initialChunkIdsWithoutCss = new Set();
|
||||
for (const c of chunk.getAllInitialChunks()) {
|
||||
(chunkHasCss(c, chunkGraph)
|
||||
? initialChunkIdsWithCss
|
||||
: initialChunkIdsWithoutCss
|
||||
).add(c.id);
|
||||
}
|
||||
|
||||
if (!withLoading && !withHmr && initialChunkIdsWithCss.size === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { createStylesheet } =
|
||||
CssLoadingRuntimeModule.getCompilationHooks(compilation);
|
||||
|
||||
const stateExpression = withHmr
|
||||
? `${RuntimeGlobals.hmrRuntimeStatePrefix}_css`
|
||||
: undefined;
|
||||
|
||||
const code = Template.asString([
|
||||
"link = document.createElement('link');",
|
||||
uniqueName
|
||||
? 'link.setAttribute("data-webpack", uniqueName + ":" + key);'
|
||||
: "",
|
||||
"link.setAttribute(loadingAttribute, 1);",
|
||||
'link.rel = "stylesheet";',
|
||||
"link.href = url;",
|
||||
crossOriginLoading
|
||||
? Template.asString([
|
||||
"if (link.src.indexOf(window.location.origin + '/') !== 0) {",
|
||||
Template.indent(
|
||||
`link.crossOrigin = ${JSON.stringify(crossOriginLoading)};`
|
||||
),
|
||||
"}"
|
||||
])
|
||||
: ""
|
||||
]);
|
||||
|
||||
const cc = str => str.charCodeAt(0);
|
||||
|
||||
return Template.asString([
|
||||
"// object to store loaded and loading chunks",
|
||||
"// undefined = chunk not loaded, null = chunk preloaded/prefetched",
|
||||
"// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded",
|
||||
`var installedChunks = ${
|
||||
stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""
|
||||
}{${Array.from(
|
||||
initialChunkIdsWithoutCss,
|
||||
id => `${JSON.stringify(id)}:0`
|
||||
).join(",")}};`,
|
||||
"",
|
||||
uniqueName
|
||||
? `var uniqueName = ${JSON.stringify(
|
||||
runtimeTemplate.outputOptions.uniqueName
|
||||
)};`
|
||||
: "// data-webpack is not used as build has no uniqueName",
|
||||
`var loadCssChunkData = ${runtimeTemplate.basicFunction(
|
||||
"target, link, chunkId",
|
||||
[
|
||||
`var data, token = "", token2, exports = {}, exportsWithId = [], exportsWithDashes = [], ${
|
||||
withHmr ? "moduleIds = [], " : ""
|
||||
}i = 0, cc = 1;`,
|
||||
"try { if(!link) link = loadStylesheet(chunkId); data = link.sheet.cssRules; data = data[data.length - 1].style; } catch(e) { data = getComputedStyle(document.head); }",
|
||||
`data = data.getPropertyValue(${
|
||||
uniqueName
|
||||
? runtimeTemplate.concatenation(
|
||||
"--webpack-",
|
||||
{ expr: "uniqueName" },
|
||||
"-",
|
||||
{ expr: "chunkId" }
|
||||
)
|
||||
: runtimeTemplate.concatenation("--webpack-", { expr: "chunkId" })
|
||||
});`,
|
||||
"if(!data) return [];",
|
||||
"for(; cc; i++) {",
|
||||
Template.indent([
|
||||
"cc = data.charCodeAt(i);",
|
||||
`if(cc == ${cc("(")}) { token2 = token; token = ""; }`,
|
||||
`else if(cc == ${cc(
|
||||
")"
|
||||
)}) { exports[token2.replace(/^_/, "")] = token.replace(/^_/, ""); token = ""; }`,
|
||||
`else if(cc == ${cc("/")} || cc == ${cc(
|
||||
"%"
|
||||
)}) { token = token.replace(/^_/, ""); exports[token] = token; exportsWithId.push(token); if(cc == ${cc(
|
||||
"%"
|
||||
)}) exportsWithDashes.push(token); token = ""; }`,
|
||||
`else if(!cc || cc == ${cc(
|
||||
","
|
||||
)}) { token = token.replace(/^_/, ""); exportsWithId.forEach(${runtimeTemplate.expressionFunction(
|
||||
`exports[x] = ${
|
||||
uniqueName
|
||||
? runtimeTemplate.concatenation(
|
||||
{ expr: "uniqueName" },
|
||||
"-",
|
||||
{ expr: "token" },
|
||||
"-",
|
||||
{ expr: "exports[x]" }
|
||||
)
|
||||
: runtimeTemplate.concatenation({ expr: "token" }, "-", {
|
||||
expr: "exports[x]"
|
||||
})
|
||||
}`,
|
||||
"x"
|
||||
)}); exportsWithDashes.forEach(${runtimeTemplate.expressionFunction(
|
||||
`exports[x] = "--" + exports[x]`,
|
||||
"x"
|
||||
)}); ${
|
||||
RuntimeGlobals.makeNamespaceObject
|
||||
}(exports); target[token] = (${runtimeTemplate.basicFunction(
|
||||
"exports, module",
|
||||
`module.exports = exports;`
|
||||
)}).bind(null, exports); ${
|
||||
withHmr
|
||||
? "moduleIds.push(token); target[token].cssExports = exports; "
|
||||
: ""
|
||||
}token = ""; exports = {}; exportsWithId.length = 0; }`,
|
||||
`else if(cc == ${cc("\\")}) { token += data[++i] }`,
|
||||
`else { token += data[i]; }`
|
||||
]),
|
||||
"}",
|
||||
`${
|
||||
withHmr ? `if(target == ${RuntimeGlobals.moduleFactories}) ` : ""
|
||||
}installedChunks[chunkId] = 0;`,
|
||||
withHmr ? "return moduleIds;" : ""
|
||||
]
|
||||
)}`,
|
||||
'var loadingAttribute = "data-webpack-loading";',
|
||||
`var loadStylesheet = ${runtimeTemplate.basicFunction(
|
||||
"chunkId, url, done" + (withHmr ? ", hmr" : ""),
|
||||
[
|
||||
'var link, needAttach, key = "chunk-" + chunkId;',
|
||||
withHmr ? "if(!hmr) {" : "",
|
||||
'var links = document.getElementsByTagName("link");',
|
||||
"for(var i = 0; i < links.length; i++) {",
|
||||
Template.indent([
|
||||
"var l = links[i];",
|
||||
`if(l.rel == "stylesheet" && (${
|
||||
withHmr
|
||||
? 'l.href.startsWith(url) || l.getAttribute("href").startsWith(url)'
|
||||
: 'l.href == url || l.getAttribute("href") == url'
|
||||
}${
|
||||
uniqueName
|
||||
? ' || l.getAttribute("data-webpack") == uniqueName + ":" + key'
|
||||
: ""
|
||||
})) { link = l; break; }`
|
||||
]),
|
||||
"}",
|
||||
"if(!done) return link;",
|
||||
withHmr ? "}" : "",
|
||||
"if(!link) {",
|
||||
Template.indent([
|
||||
"needAttach = true;",
|
||||
createStylesheet.call(code, this.chunk)
|
||||
]),
|
||||
"}",
|
||||
`var onLinkComplete = ${runtimeTemplate.basicFunction(
|
||||
"prev, event",
|
||||
Template.asString([
|
||||
"link.onerror = link.onload = null;",
|
||||
"link.removeAttribute(loadingAttribute);",
|
||||
"clearTimeout(timeout);",
|
||||
'if(event && event.type != "load") link.parentNode.removeChild(link)',
|
||||
"done(event);",
|
||||
"if(prev) return prev(event);"
|
||||
])
|
||||
)};`,
|
||||
"if(link.getAttribute(loadingAttribute)) {",
|
||||
Template.indent([
|
||||
`var timeout = setTimeout(onLinkComplete.bind(null, undefined, { type: 'timeout', target: link }), ${loadTimeout});`,
|
||||
"link.onerror = onLinkComplete.bind(null, link.onerror);",
|
||||
"link.onload = onLinkComplete.bind(null, link.onload);"
|
||||
]),
|
||||
"} else onLinkComplete(undefined, { type: 'load', target: link });", // We assume any existing stylesheet is render blocking
|
||||
withHmr ? "hmr ? document.head.insertBefore(link, hmr) :" : "",
|
||||
"needAttach && document.head.appendChild(link);",
|
||||
"return link;"
|
||||
]
|
||||
)};`,
|
||||
initialChunkIdsWithCss.size > 2
|
||||
? `${JSON.stringify(
|
||||
Array.from(initialChunkIdsWithCss)
|
||||
)}.forEach(loadCssChunkData.bind(null, ${
|
||||
RuntimeGlobals.moduleFactories
|
||||
}, 0));`
|
||||
: initialChunkIdsWithCss.size > 0
|
||||
? `${Array.from(
|
||||
initialChunkIdsWithCss,
|
||||
id =>
|
||||
`loadCssChunkData(${
|
||||
RuntimeGlobals.moduleFactories
|
||||
}, 0, ${JSON.stringify(id)});`
|
||||
).join("")}`
|
||||
: "// no initial css",
|
||||
"",
|
||||
withLoading
|
||||
? Template.asString([
|
||||
`${fn}.css = ${runtimeTemplate.basicFunction(
|
||||
"chunkId, promises",
|
||||
hasCssMatcher !== false
|
||||
? [
|
||||
"// css chunk loading",
|
||||
`var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`,
|
||||
'if(installedChunkData !== 0) { // 0 means "already installed".',
|
||||
Template.indent([
|
||||
"",
|
||||
'// a Promise means "currently loading".',
|
||||
"if(installedChunkData) {",
|
||||
Template.indent([
|
||||
"promises.push(installedChunkData[2]);"
|
||||
]),
|
||||
"} else {",
|
||||
Template.indent([
|
||||
hasCssMatcher === true
|
||||
? "if(true) { // all chunks have CSS"
|
||||
: `if(${hasCssMatcher("chunkId")}) {`,
|
||||
Template.indent([
|
||||
"// setup Promise in chunk cache",
|
||||
`var promise = new Promise(${runtimeTemplate.expressionFunction(
|
||||
`installedChunkData = installedChunks[chunkId] = [resolve, reject]`,
|
||||
"resolve, reject"
|
||||
)});`,
|
||||
"promises.push(installedChunkData[2] = promise);",
|
||||
"",
|
||||
"// start chunk loading",
|
||||
`var url = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(chunkId);`,
|
||||
"// create error before stack unwound to get useful stacktrace later",
|
||||
"var error = new Error();",
|
||||
`var loadingEnded = ${runtimeTemplate.basicFunction(
|
||||
"event",
|
||||
[
|
||||
`if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId)) {`,
|
||||
Template.indent([
|
||||
"installedChunkData = installedChunks[chunkId];",
|
||||
"if(installedChunkData !== 0) installedChunks[chunkId] = undefined;",
|
||||
"if(installedChunkData) {",
|
||||
Template.indent([
|
||||
'if(event.type !== "load") {',
|
||||
Template.indent([
|
||||
"var errorType = event && event.type;",
|
||||
"var realSrc = event && event.target && event.target.src;",
|
||||
"error.message = 'Loading css chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
|
||||
"error.name = 'ChunkLoadError';",
|
||||
"error.type = errorType;",
|
||||
"error.request = realSrc;",
|
||||
"installedChunkData[1](error);"
|
||||
]),
|
||||
"} else {",
|
||||
Template.indent([
|
||||
`loadCssChunkData(${RuntimeGlobals.moduleFactories}, link, chunkId);`,
|
||||
"installedChunkData[0]();"
|
||||
]),
|
||||
"}"
|
||||
]),
|
||||
"}"
|
||||
]),
|
||||
"}"
|
||||
]
|
||||
)};`,
|
||||
"var link = loadStylesheet(chunkId, url, loadingEnded);"
|
||||
]),
|
||||
"} else installedChunks[chunkId] = 0;"
|
||||
]),
|
||||
"}"
|
||||
]),
|
||||
"}"
|
||||
]
|
||||
: "installedChunks[chunkId] = 0;"
|
||||
)};`
|
||||
])
|
||||
: "// no chunk loading",
|
||||
"",
|
||||
withHmr
|
||||
? Template.asString([
|
||||
"var oldTags = [];",
|
||||
"var newTags = [];",
|
||||
`var applyHandler = ${runtimeTemplate.basicFunction("options", [
|
||||
`return { dispose: ${runtimeTemplate.basicFunction(
|
||||
"",
|
||||
[]
|
||||
)}, apply: ${runtimeTemplate.basicFunction("", [
|
||||
"var moduleIds = [];",
|
||||
`newTags.forEach(${runtimeTemplate.expressionFunction(
|
||||
"info[1].sheet.disabled = false",
|
||||
"info"
|
||||
)});`,
|
||||
"while(oldTags.length) {",
|
||||
Template.indent([
|
||||
"var oldTag = oldTags.pop();",
|
||||
"if(oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);"
|
||||
]),
|
||||
"}",
|
||||
"while(newTags.length) {",
|
||||
Template.indent([
|
||||
`var info = newTags.pop();`,
|
||||
`var chunkModuleIds = loadCssChunkData(${RuntimeGlobals.moduleFactories}, info[1], info[0]);`,
|
||||
`chunkModuleIds.forEach(${runtimeTemplate.expressionFunction(
|
||||
"moduleIds.push(id)",
|
||||
"id"
|
||||
)});`
|
||||
]),
|
||||
"}",
|
||||
"return moduleIds;"
|
||||
])} };`
|
||||
])}`,
|
||||
`var cssTextKey = ${runtimeTemplate.returningFunction(
|
||||
`Array.from(link.sheet.cssRules, ${runtimeTemplate.returningFunction(
|
||||
"r.cssText",
|
||||
"r"
|
||||
)}).join()`,
|
||||
"link"
|
||||
)}`,
|
||||
`${
|
||||
RuntimeGlobals.hmrDownloadUpdateHandlers
|
||||
}.css = ${runtimeTemplate.basicFunction(
|
||||
"chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList",
|
||||
[
|
||||
"applyHandlers.push(applyHandler);",
|
||||
`chunkIds.forEach(${runtimeTemplate.basicFunction("chunkId", [
|
||||
`var filename = ${RuntimeGlobals.getChunkCssFilename}(chunkId);`,
|
||||
`var url = ${RuntimeGlobals.publicPath} + filename;`,
|
||||
"var oldTag = loadStylesheet(chunkId, url);",
|
||||
"if(!oldTag) return;",
|
||||
`promises.push(new Promise(${runtimeTemplate.basicFunction(
|
||||
"resolve, reject",
|
||||
[
|
||||
`var link = loadStylesheet(chunkId, url + (url.indexOf("?") < 0 ? "?" : "&") + "hmr=" + Date.now(), ${runtimeTemplate.basicFunction(
|
||||
"event",
|
||||
[
|
||||
'if(event.type !== "load") {',
|
||||
Template.indent([
|
||||
"var errorType = event && event.type;",
|
||||
"var realSrc = event && event.target && event.target.src;",
|
||||
"error.message = 'Loading css hot update chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
|
||||
"error.name = 'ChunkLoadError';",
|
||||
"error.type = errorType;",
|
||||
"error.request = realSrc;",
|
||||
"reject(error);"
|
||||
]),
|
||||
"} else {",
|
||||
Template.indent([
|
||||
"try { if(cssTextKey(oldTag) == cssTextKey(link)) { if(link.parentNode) link.parentNode.removeChild(link); return resolve(); } } catch(e) {}",
|
||||
"var factories = {};",
|
||||
"loadCssChunkData(factories, link, chunkId);",
|
||||
`Object.keys(factories).forEach(${runtimeTemplate.expressionFunction(
|
||||
"updatedModulesList.push(id)",
|
||||
"id"
|
||||
)})`,
|
||||
"link.sheet.disabled = true;",
|
||||
"oldTags.push(oldTag);",
|
||||
"newTags.push([chunkId, link]);",
|
||||
"resolve();"
|
||||
]),
|
||||
"}"
|
||||
]
|
||||
)}, oldTag);`
|
||||
]
|
||||
)}));`
|
||||
])});`
|
||||
]
|
||||
)}`
|
||||
])
|
||||
: "// no hmr"
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CssLoadingRuntimeModule;
|
|
@ -0,0 +1,447 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { ConcatSource } = require("webpack-sources");
|
||||
const HotUpdateChunk = require("../HotUpdateChunk");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const SelfModuleFactory = require("../SelfModuleFactory");
|
||||
const CssExportDependency = require("../dependencies/CssExportDependency");
|
||||
const CssImportDependency = require("../dependencies/CssImportDependency");
|
||||
const CssLocalIdentifierDependency = require("../dependencies/CssLocalIdentifierDependency");
|
||||
const CssSelfLocalIdentifierDependency = require("../dependencies/CssSelfLocalIdentifierDependency");
|
||||
const CssUrlDependency = require("../dependencies/CssUrlDependency");
|
||||
const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
|
||||
const { compareModulesByIdentifier } = require("../util/comparators");
|
||||
const createSchemaValidation = require("../util/create-schema-validation");
|
||||
const createHash = require("../util/createHash");
|
||||
const memoize = require("../util/memoize");
|
||||
const CssGenerator = require("./CssGenerator");
|
||||
const CssParser = require("./CssParser");
|
||||
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("../Chunk")} Chunk */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
/** @typedef {import("../Module")} Module */
|
||||
|
||||
const getCssLoadingRuntimeModule = memoize(() =>
|
||||
require("./CssLoadingRuntimeModule")
|
||||
);
|
||||
|
||||
const getSchema = name => {
|
||||
const { definitions } = require("../../schemas/WebpackOptions.json");
|
||||
return {
|
||||
definitions,
|
||||
oneOf: [{ $ref: `#/definitions/${name}` }]
|
||||
};
|
||||
};
|
||||
|
||||
const validateGeneratorOptions = createSchemaValidation(
|
||||
require("../../schemas/plugins/css/CssGeneratorOptions.check.js"),
|
||||
() => getSchema("CssGeneratorOptions"),
|
||||
{
|
||||
name: "Css Modules Plugin",
|
||||
baseDataPath: "parser"
|
||||
}
|
||||
);
|
||||
const validateParserOptions = createSchemaValidation(
|
||||
require("../../schemas/plugins/css/CssParserOptions.check.js"),
|
||||
() => getSchema("CssParserOptions"),
|
||||
{
|
||||
name: "Css Modules Plugin",
|
||||
baseDataPath: "parser"
|
||||
}
|
||||
);
|
||||
|
||||
const escapeCss = (str, omitOptionalUnderscore) => {
|
||||
const escaped = `${str}`.replace(
|
||||
// cspell:word uffff
|
||||
/[^a-zA-Z0-9_\u0081-\uffff-]/g,
|
||||
s => `\\${s}`
|
||||
);
|
||||
return !omitOptionalUnderscore && /^(?!--)[0-9_-]/.test(escaped)
|
||||
? `_${escaped}`
|
||||
: escaped;
|
||||
};
|
||||
|
||||
const plugin = "CssModulesPlugin";
|
||||
|
||||
class CssModulesPlugin {
|
||||
/**
|
||||
* Apply the plugin
|
||||
* @param {Compiler} compiler the compiler instance
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
compiler.hooks.compilation.tap(
|
||||
plugin,
|
||||
(compilation, { normalModuleFactory }) => {
|
||||
const selfFactory = new SelfModuleFactory(compilation.moduleGraph);
|
||||
compilation.dependencyFactories.set(
|
||||
CssUrlDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
compilation.dependencyTemplates.set(
|
||||
CssUrlDependency,
|
||||
new CssUrlDependency.Template()
|
||||
);
|
||||
compilation.dependencyTemplates.set(
|
||||
CssLocalIdentifierDependency,
|
||||
new CssLocalIdentifierDependency.Template()
|
||||
);
|
||||
compilation.dependencyFactories.set(
|
||||
CssSelfLocalIdentifierDependency,
|
||||
selfFactory
|
||||
);
|
||||
compilation.dependencyTemplates.set(
|
||||
CssSelfLocalIdentifierDependency,
|
||||
new CssSelfLocalIdentifierDependency.Template()
|
||||
);
|
||||
compilation.dependencyTemplates.set(
|
||||
CssExportDependency,
|
||||
new CssExportDependency.Template()
|
||||
);
|
||||
compilation.dependencyFactories.set(
|
||||
CssImportDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
compilation.dependencyTemplates.set(
|
||||
CssImportDependency,
|
||||
new CssImportDependency.Template()
|
||||
);
|
||||
compilation.dependencyTemplates.set(
|
||||
StaticExportsDependency,
|
||||
new StaticExportsDependency.Template()
|
||||
);
|
||||
normalModuleFactory.hooks.createParser
|
||||
.for("css")
|
||||
.tap(plugin, parserOptions => {
|
||||
validateParserOptions(parserOptions);
|
||||
return new CssParser();
|
||||
});
|
||||
normalModuleFactory.hooks.createParser
|
||||
.for("css/global")
|
||||
.tap(plugin, parserOptions => {
|
||||
validateParserOptions(parserOptions);
|
||||
return new CssParser({
|
||||
allowPseudoBlocks: false,
|
||||
allowModeSwitch: false
|
||||
});
|
||||
});
|
||||
normalModuleFactory.hooks.createParser
|
||||
.for("css/module")
|
||||
.tap(plugin, parserOptions => {
|
||||
validateParserOptions(parserOptions);
|
||||
return new CssParser({
|
||||
defaultMode: "local"
|
||||
});
|
||||
});
|
||||
normalModuleFactory.hooks.createGenerator
|
||||
.for("css")
|
||||
.tap(plugin, generatorOptions => {
|
||||
validateGeneratorOptions(generatorOptions);
|
||||
return new CssGenerator();
|
||||
});
|
||||
normalModuleFactory.hooks.createGenerator
|
||||
.for("css/global")
|
||||
.tap(plugin, generatorOptions => {
|
||||
validateGeneratorOptions(generatorOptions);
|
||||
return new CssGenerator();
|
||||
});
|
||||
normalModuleFactory.hooks.createGenerator
|
||||
.for("css/module")
|
||||
.tap(plugin, generatorOptions => {
|
||||
validateGeneratorOptions(generatorOptions);
|
||||
return new CssGenerator();
|
||||
});
|
||||
const orderedCssModulesPerChunk = new WeakMap();
|
||||
compilation.hooks.afterCodeGeneration.tap("CssModulesPlugin", () => {
|
||||
const { chunkGraph } = compilation;
|
||||
for (const chunk of compilation.chunks) {
|
||||
if (CssModulesPlugin.chunkHasCss(chunk, chunkGraph)) {
|
||||
orderedCssModulesPerChunk.set(
|
||||
chunk,
|
||||
this.getOrderedChunkCssModules(chunk, chunkGraph, compilation)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
compilation.hooks.contentHash.tap("CssModulesPlugin", chunk => {
|
||||
const {
|
||||
chunkGraph,
|
||||
outputOptions: {
|
||||
hashSalt,
|
||||
hashDigest,
|
||||
hashDigestLength,
|
||||
hashFunction
|
||||
}
|
||||
} = compilation;
|
||||
const modules = orderedCssModulesPerChunk.get(chunk);
|
||||
if (modules === undefined) return;
|
||||
const hash = createHash(hashFunction);
|
||||
if (hashSalt) hash.update(hashSalt);
|
||||
for (const module of modules) {
|
||||
hash.update(chunkGraph.getModuleHash(module, chunk.runtime));
|
||||
}
|
||||
const digest = /** @type {string} */ (hash.digest(hashDigest));
|
||||
chunk.contentHash.css = digest.substr(0, hashDigestLength);
|
||||
});
|
||||
compilation.hooks.renderManifest.tap(plugin, (result, options) => {
|
||||
const { chunkGraph } = compilation;
|
||||
const { hash, chunk, codeGenerationResults } = options;
|
||||
|
||||
if (chunk instanceof HotUpdateChunk) return result;
|
||||
|
||||
const modules = orderedCssModulesPerChunk.get(chunk);
|
||||
if (modules !== undefined) {
|
||||
result.push({
|
||||
render: () =>
|
||||
this.renderChunk({
|
||||
chunk,
|
||||
chunkGraph,
|
||||
codeGenerationResults,
|
||||
uniqueName: compilation.outputOptions.uniqueName,
|
||||
modules
|
||||
}),
|
||||
filenameTemplate: CssModulesPlugin.getChunkFilenameTemplate(
|
||||
chunk,
|
||||
compilation.outputOptions
|
||||
),
|
||||
pathOptions: {
|
||||
hash,
|
||||
runtime: chunk.runtime,
|
||||
chunk,
|
||||
contentHashType: "css"
|
||||
},
|
||||
identifier: `css${chunk.id}`,
|
||||
hash: chunk.contentHash.css
|
||||
});
|
||||
}
|
||||
return result;
|
||||
});
|
||||
const enabledChunks = new WeakSet();
|
||||
const handler = (chunk, set) => {
|
||||
if (enabledChunks.has(chunk)) {
|
||||
return;
|
||||
}
|
||||
enabledChunks.add(chunk);
|
||||
|
||||
set.add(RuntimeGlobals.publicPath);
|
||||
set.add(RuntimeGlobals.getChunkCssFilename);
|
||||
set.add(RuntimeGlobals.hasOwnProperty);
|
||||
set.add(RuntimeGlobals.moduleFactoriesAddOnly);
|
||||
set.add(RuntimeGlobals.makeNamespaceObject);
|
||||
|
||||
const CssLoadingRuntimeModule = getCssLoadingRuntimeModule();
|
||||
compilation.addRuntimeModule(chunk, new CssLoadingRuntimeModule(set));
|
||||
};
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.hasCssModules)
|
||||
.tap(plugin, handler);
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.ensureChunkHandlers)
|
||||
.tap(plugin, handler);
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
|
||||
.tap(plugin, handler);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
getModulesInOrder(chunk, modules, compilation) {
|
||||
if (!modules) return [];
|
||||
|
||||
const modulesList = [...modules];
|
||||
|
||||
// Get ordered list of modules per chunk group
|
||||
// Lists are in reverse order to allow to use Array.pop()
|
||||
const modulesByChunkGroup = Array.from(chunk.groupsIterable, chunkGroup => {
|
||||
const sortedModules = modulesList
|
||||
.map(module => {
|
||||
return {
|
||||
module,
|
||||
index: chunkGroup.getModulePostOrderIndex(module)
|
||||
};
|
||||
})
|
||||
.filter(item => item.index !== undefined)
|
||||
.sort((a, b) => b.index - a.index)
|
||||
.map(item => item.module);
|
||||
|
||||
return { list: sortedModules, set: new Set(sortedModules) };
|
||||
});
|
||||
|
||||
if (modulesByChunkGroup.length === 1)
|
||||
return modulesByChunkGroup[0].list.reverse();
|
||||
|
||||
const compareModuleLists = ({ list: a }, { list: b }) => {
|
||||
if (a.length === 0) {
|
||||
return b.length === 0 ? 0 : 1;
|
||||
} else {
|
||||
if (b.length === 0) return -1;
|
||||
return compareModulesByIdentifier(a[a.length - 1], b[b.length - 1]);
|
||||
}
|
||||
};
|
||||
|
||||
modulesByChunkGroup.sort(compareModuleLists);
|
||||
|
||||
const finalModules = [];
|
||||
|
||||
for (;;) {
|
||||
const failedModules = new Set();
|
||||
const list = modulesByChunkGroup[0].list;
|
||||
if (list.length === 0) {
|
||||
// done, everything empty
|
||||
break;
|
||||
}
|
||||
let selectedModule = list[list.length - 1];
|
||||
let hasFailed = undefined;
|
||||
outer: for (;;) {
|
||||
for (const { list, set } of modulesByChunkGroup) {
|
||||
if (list.length === 0) continue;
|
||||
const lastModule = list[list.length - 1];
|
||||
if (lastModule === selectedModule) continue;
|
||||
if (!set.has(selectedModule)) continue;
|
||||
failedModules.add(selectedModule);
|
||||
if (failedModules.has(lastModule)) {
|
||||
// There is a conflict, try other alternatives
|
||||
hasFailed = lastModule;
|
||||
continue;
|
||||
}
|
||||
selectedModule = lastModule;
|
||||
hasFailed = false;
|
||||
continue outer; // restart
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (hasFailed) {
|
||||
// There is a not resolve-able conflict with the selectedModule
|
||||
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(
|
||||
compilation.requestShortener
|
||||
)}`
|
||||
)
|
||||
);
|
||||
}
|
||||
selectedModule = hasFailed;
|
||||
}
|
||||
// Insert the selected module into the final modules list
|
||||
finalModules.push(selectedModule);
|
||||
// Remove the selected module from all lists
|
||||
for (const { list, set } of modulesByChunkGroup) {
|
||||
const lastModule = list[list.length - 1];
|
||||
if (lastModule === selectedModule) list.pop();
|
||||
else if (hasFailed && set.has(selectedModule)) {
|
||||
const idx = list.indexOf(selectedModule);
|
||||
if (idx >= 0) list.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
modulesByChunkGroup.sort(compareModuleLists);
|
||||
}
|
||||
return finalModules;
|
||||
}
|
||||
|
||||
getOrderedChunkCssModules(chunk, chunkGraph, compilation) {
|
||||
return [
|
||||
...this.getModulesInOrder(
|
||||
chunk,
|
||||
chunkGraph.getOrderedChunkModulesIterableBySourceType(
|
||||
chunk,
|
||||
"css-import",
|
||||
compareModulesByIdentifier
|
||||
),
|
||||
compilation
|
||||
),
|
||||
...this.getModulesInOrder(
|
||||
chunk,
|
||||
chunkGraph.getOrderedChunkModulesIterableBySourceType(
|
||||
chunk,
|
||||
"css",
|
||||
compareModulesByIdentifier
|
||||
),
|
||||
compilation
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
renderChunk({
|
||||
uniqueName,
|
||||
chunk,
|
||||
chunkGraph,
|
||||
codeGenerationResults,
|
||||
modules
|
||||
}) {
|
||||
const source = new ConcatSource();
|
||||
const metaData = [];
|
||||
for (const module of modules) {
|
||||
try {
|
||||
const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
|
||||
|
||||
const s =
|
||||
codeGenResult.sources.get("css") ||
|
||||
codeGenResult.sources.get("css-import");
|
||||
if (s) {
|
||||
source.add(s);
|
||||
source.add("\n");
|
||||
}
|
||||
const exports =
|
||||
codeGenResult.data && codeGenResult.data.get("css-exports");
|
||||
const moduleId = chunkGraph.getModuleId(module) + "";
|
||||
metaData.push(
|
||||
`${
|
||||
exports
|
||||
? Array.from(exports, ([n, v]) => {
|
||||
const shortcutValue = `${
|
||||
uniqueName ? uniqueName + "-" : ""
|
||||
}${moduleId}-${n}`;
|
||||
return v === shortcutValue
|
||||
? `${escapeCss(n)}/`
|
||||
: v === "--" + shortcutValue
|
||||
? `${escapeCss(n)}%`
|
||||
: `${escapeCss(n)}(${escapeCss(v)})`;
|
||||
}).join("")
|
||||
: ""
|
||||
}${escapeCss(moduleId)}`
|
||||
);
|
||||
} catch (e) {
|
||||
e.message += `\nduring rendering of css ${module.identifier()}`;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
source.add(
|
||||
`head{--webpack-${escapeCss(
|
||||
(uniqueName ? uniqueName + "-" : "") + chunk.id,
|
||||
true
|
||||
)}:${metaData.join(",")};}`
|
||||
);
|
||||
return source;
|
||||
}
|
||||
|
||||
static getChunkFilenameTemplate(chunk, outputOptions) {
|
||||
if (chunk.cssFilenameTemplate) {
|
||||
return chunk.cssFilenameTemplate;
|
||||
} else if (chunk.canBeInitial()) {
|
||||
return outputOptions.cssFilename;
|
||||
} else {
|
||||
return outputOptions.cssChunkFilename;
|
||||
}
|
||||
}
|
||||
|
||||
static chunkHasCss(chunk, chunkGraph) {
|
||||
return (
|
||||
!!chunkGraph.getChunkModulesIterableBySourceType(chunk, "css") ||
|
||||
!!chunkGraph.getChunkModulesIterableBySourceType(chunk, "css-import")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CssModulesPlugin;
|
|
@ -0,0 +1,618 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const Parser = require("../Parser");
|
||||
const ConstDependency = require("../dependencies/ConstDependency");
|
||||
const CssExportDependency = require("../dependencies/CssExportDependency");
|
||||
const CssImportDependency = require("../dependencies/CssImportDependency");
|
||||
const CssLocalIdentifierDependency = require("../dependencies/CssLocalIdentifierDependency");
|
||||
const CssSelfLocalIdentifierDependency = require("../dependencies/CssSelfLocalIdentifierDependency");
|
||||
const CssUrlDependency = require("../dependencies/CssUrlDependency");
|
||||
const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
|
||||
const walkCssTokens = require("./walkCssTokens");
|
||||
|
||||
/** @typedef {import("../Parser").ParserState} ParserState */
|
||||
/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
|
||||
|
||||
const CC_LEFT_CURLY = "{".charCodeAt(0);
|
||||
const CC_RIGHT_CURLY = "}".charCodeAt(0);
|
||||
const CC_COLON = ":".charCodeAt(0);
|
||||
const CC_SLASH = "/".charCodeAt(0);
|
||||
const CC_SEMICOLON = ";".charCodeAt(0);
|
||||
|
||||
const cssUnescape = str => {
|
||||
return str.replace(/\\([0-9a-fA-F]{1,6}[ \t\n\r\f]?|[\s\S])/g, match => {
|
||||
if (match.length > 2) {
|
||||
return String.fromCharCode(parseInt(match.slice(1).trim(), 16));
|
||||
} else {
|
||||
return match[1];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
class LocConverter {
|
||||
constructor(input) {
|
||||
this._input = input;
|
||||
this.line = 1;
|
||||
this.column = 0;
|
||||
this.pos = 0;
|
||||
}
|
||||
|
||||
get(pos) {
|
||||
if (this.pos !== pos) {
|
||||
if (this.pos < pos) {
|
||||
const str = this._input.slice(this.pos, pos);
|
||||
let i = str.lastIndexOf("\n");
|
||||
if (i === -1) {
|
||||
this.column += str.length;
|
||||
} else {
|
||||
this.column = str.length - i - 1;
|
||||
this.line++;
|
||||
while (i > 0 && (i = str.lastIndexOf("\n", i - 1)) !== -1)
|
||||
this.line++;
|
||||
}
|
||||
} else {
|
||||
let i = this._input.lastIndexOf("\n", this.pos);
|
||||
while (i >= pos) {
|
||||
this.line--;
|
||||
i = i > 0 ? this._input.lastIndexOf("\n", i - 1) : -1;
|
||||
}
|
||||
this.column = pos - i;
|
||||
}
|
||||
this.pos = pos;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
const CSS_MODE_TOP_LEVEL = 0;
|
||||
const CSS_MODE_IN_RULE = 1;
|
||||
const CSS_MODE_IN_LOCAL_RULE = 2;
|
||||
const CSS_MODE_AT_IMPORT_EXPECT_URL = 3;
|
||||
// TODO implement layer and supports for @import
|
||||
const CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS = 4;
|
||||
const CSS_MODE_AT_IMPORT_EXPECT_MEDIA = 5;
|
||||
const CSS_MODE_AT_OTHER = 6;
|
||||
|
||||
const explainMode = mode => {
|
||||
switch (mode) {
|
||||
case CSS_MODE_TOP_LEVEL:
|
||||
return "parsing top level css";
|
||||
case CSS_MODE_IN_RULE:
|
||||
return "parsing css rule content (global)";
|
||||
case CSS_MODE_IN_LOCAL_RULE:
|
||||
return "parsing css rule content (local)";
|
||||
case CSS_MODE_AT_IMPORT_EXPECT_URL:
|
||||
return "parsing @import (expecting url)";
|
||||
case CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS:
|
||||
return "parsing @import (expecting optionally supports or media query)";
|
||||
case CSS_MODE_AT_IMPORT_EXPECT_MEDIA:
|
||||
return "parsing @import (expecting optionally media query)";
|
||||
case CSS_MODE_AT_OTHER:
|
||||
return "parsing at-rule";
|
||||
default:
|
||||
return mode;
|
||||
}
|
||||
};
|
||||
|
||||
class CssParser extends Parser {
|
||||
constructor({
|
||||
allowPseudoBlocks = true,
|
||||
allowModeSwitch = true,
|
||||
defaultMode = "global"
|
||||
} = {}) {
|
||||
super();
|
||||
this.allowPseudoBlocks = allowPseudoBlocks;
|
||||
this.allowModeSwitch = allowModeSwitch;
|
||||
this.defaultMode = defaultMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | Buffer | PreparsedAst} source the source to parse
|
||||
* @param {ParserState} state the parser state
|
||||
* @returns {ParserState} the parser state
|
||||
*/
|
||||
parse(source, state) {
|
||||
if (Buffer.isBuffer(source)) {
|
||||
source = source.toString("utf-8");
|
||||
} else if (typeof source === "object") {
|
||||
throw new Error("webpackAst is unexpected for the CssParser");
|
||||
}
|
||||
if (source[0] === "\ufeff") {
|
||||
source = source.slice(1);
|
||||
}
|
||||
|
||||
const module = state.module;
|
||||
|
||||
const declaredCssVariables = new Set();
|
||||
|
||||
const locConverter = new LocConverter(source);
|
||||
let mode = CSS_MODE_TOP_LEVEL;
|
||||
let modePos = 0;
|
||||
let modeNestingLevel = 0;
|
||||
let modeData = undefined;
|
||||
let singleClassSelector = undefined;
|
||||
let lastIdentifier = undefined;
|
||||
const modeStack = [];
|
||||
const isTopLevelLocal = () =>
|
||||
modeData === "local" ||
|
||||
(this.defaultMode === "local" && modeData === undefined);
|
||||
const eatWhiteLine = (input, pos) => {
|
||||
for (;;) {
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (cc === 32 || cc === 9) {
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
if (cc === 10) pos++;
|
||||
break;
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
const eatUntil = chars => {
|
||||
const charCodes = Array.from({ length: chars.length }, (_, i) =>
|
||||
chars.charCodeAt(i)
|
||||
);
|
||||
const arr = Array.from(
|
||||
{ length: charCodes.reduce((a, b) => Math.max(a, b), 0) + 1 },
|
||||
() => false
|
||||
);
|
||||
charCodes.forEach(cc => (arr[cc] = true));
|
||||
return (input, pos) => {
|
||||
for (;;) {
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (cc < arr.length && arr[cc]) {
|
||||
return pos;
|
||||
}
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
}
|
||||
};
|
||||
};
|
||||
const eatText = (input, pos, eater) => {
|
||||
let text = "";
|
||||
for (;;) {
|
||||
if (input.charCodeAt(pos) === CC_SLASH) {
|
||||
const newPos = walkCssTokens.eatComments(input, pos);
|
||||
if (pos !== newPos) {
|
||||
pos = newPos;
|
||||
if (pos === input.length) break;
|
||||
} else {
|
||||
text += "/";
|
||||
pos++;
|
||||
if (pos === input.length) break;
|
||||
}
|
||||
}
|
||||
const newPos = eater(input, pos);
|
||||
if (pos !== newPos) {
|
||||
text += input.slice(pos, newPos);
|
||||
pos = newPos;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (pos === input.length) break;
|
||||
}
|
||||
return [pos, text.trimRight()];
|
||||
};
|
||||
const eatExportName = eatUntil(":};/");
|
||||
const eatExportValue = eatUntil("};/");
|
||||
const parseExports = (input, pos) => {
|
||||
pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (cc !== CC_LEFT_CURLY)
|
||||
throw new Error(
|
||||
`Unexpected ${input[pos]} at ${pos} during parsing of ':export' (expected '{')`
|
||||
);
|
||||
pos++;
|
||||
pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
||||
for (;;) {
|
||||
if (input.charCodeAt(pos) === CC_RIGHT_CURLY) break;
|
||||
pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
||||
if (pos === input.length) return pos;
|
||||
let start = pos;
|
||||
let name;
|
||||
[pos, name] = eatText(input, pos, eatExportName);
|
||||
if (pos === input.length) return pos;
|
||||
if (input.charCodeAt(pos) !== CC_COLON) {
|
||||
throw new Error(
|
||||
`Unexpected ${input[pos]} at ${pos} during parsing of export name in ':export' (expected ':')`
|
||||
);
|
||||
}
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
||||
if (pos === input.length) return pos;
|
||||
let value;
|
||||
[pos, value] = eatText(input, pos, eatExportValue);
|
||||
if (pos === input.length) return pos;
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (cc === CC_SEMICOLON) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
||||
if (pos === input.length) return pos;
|
||||
} else if (cc !== CC_RIGHT_CURLY) {
|
||||
throw new Error(
|
||||
`Unexpected ${input[pos]} at ${pos} during parsing of export value in ':export' (expected ';' or '}')`
|
||||
);
|
||||
}
|
||||
const dep = new CssExportDependency(name, value);
|
||||
const { line: sl, column: sc } = locConverter.get(start);
|
||||
const { line: el, column: ec } = locConverter.get(pos);
|
||||
dep.setLoc(sl, sc, el, ec);
|
||||
module.addDependency(dep);
|
||||
}
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
pos = eatWhiteLine(input, pos);
|
||||
return pos;
|
||||
};
|
||||
const eatPropertyName = eatUntil(":{};");
|
||||
const processLocalDeclaration = (input, pos) => {
|
||||
modeData = undefined;
|
||||
const start = pos;
|
||||
pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
||||
const propertyNameStart = pos;
|
||||
const [propertyNameEnd, propertyName] = eatText(
|
||||
input,
|
||||
pos,
|
||||
eatPropertyName
|
||||
);
|
||||
if (input.charCodeAt(propertyNameEnd) !== CC_COLON) return start;
|
||||
pos = propertyNameEnd + 1;
|
||||
if (propertyName.startsWith("--")) {
|
||||
// CSS Variable
|
||||
const { line: sl, column: sc } = locConverter.get(propertyNameStart);
|
||||
const { line: el, column: ec } = locConverter.get(propertyNameEnd);
|
||||
const name = propertyName.slice(2);
|
||||
const dep = new CssLocalIdentifierDependency(
|
||||
name,
|
||||
[propertyNameStart, propertyNameEnd],
|
||||
"--"
|
||||
);
|
||||
dep.setLoc(sl, sc, el, ec);
|
||||
module.addDependency(dep);
|
||||
declaredCssVariables.add(name);
|
||||
} else if (
|
||||
propertyName === "animation-name" ||
|
||||
propertyName === "animation"
|
||||
) {
|
||||
modeData = "animation";
|
||||
lastIdentifier = undefined;
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
const processDeclarationValueDone = (input, pos) => {
|
||||
if (modeData === "animation" && lastIdentifier) {
|
||||
const { line: sl, column: sc } = locConverter.get(lastIdentifier[0]);
|
||||
const { line: el, column: ec } = locConverter.get(lastIdentifier[1]);
|
||||
const name = input.slice(lastIdentifier[0], lastIdentifier[1]);
|
||||
const dep = new CssSelfLocalIdentifierDependency(name, lastIdentifier);
|
||||
dep.setLoc(sl, sc, el, ec);
|
||||
module.addDependency(dep);
|
||||
}
|
||||
};
|
||||
const eatKeyframes = eatUntil("{};/");
|
||||
const eatNameInVar = eatUntil(",)};/");
|
||||
walkCssTokens(source, {
|
||||
isSelector: () => {
|
||||
return mode !== CSS_MODE_IN_RULE && mode !== CSS_MODE_IN_LOCAL_RULE;
|
||||
},
|
||||
url: (input, start, end, contentStart, contentEnd) => {
|
||||
const value = cssUnescape(input.slice(contentStart, contentEnd));
|
||||
switch (mode) {
|
||||
case CSS_MODE_AT_IMPORT_EXPECT_URL: {
|
||||
modeData.url = value;
|
||||
mode = CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS;
|
||||
break;
|
||||
}
|
||||
case CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS:
|
||||
case CSS_MODE_AT_IMPORT_EXPECT_MEDIA:
|
||||
throw new Error(
|
||||
`Unexpected ${input.slice(
|
||||
start,
|
||||
end
|
||||
)} at ${start} during ${explainMode(mode)}`
|
||||
);
|
||||
default: {
|
||||
const dep = new CssUrlDependency(value, [start, end], "url");
|
||||
const { line: sl, column: sc } = locConverter.get(start);
|
||||
const { line: el, column: ec } = locConverter.get(end);
|
||||
dep.setLoc(sl, sc, el, ec);
|
||||
module.addDependency(dep);
|
||||
module.addCodeGenerationDependency(dep);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return end;
|
||||
},
|
||||
string: (input, start, end) => {
|
||||
switch (mode) {
|
||||
case CSS_MODE_AT_IMPORT_EXPECT_URL: {
|
||||
modeData.url = cssUnescape(input.slice(start + 1, end - 1));
|
||||
mode = CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return end;
|
||||
},
|
||||
atKeyword: (input, start, end) => {
|
||||
const name = input.slice(start, end);
|
||||
if (name === "@namespace") {
|
||||
throw new Error("@namespace is not supported in bundled CSS");
|
||||
}
|
||||
if (name === "@import") {
|
||||
if (mode !== CSS_MODE_TOP_LEVEL) {
|
||||
throw new Error(
|
||||
`Unexpected @import at ${start} during ${explainMode(mode)}`
|
||||
);
|
||||
}
|
||||
mode = CSS_MODE_AT_IMPORT_EXPECT_URL;
|
||||
modePos = end;
|
||||
modeData = {
|
||||
start: start,
|
||||
url: undefined,
|
||||
supports: undefined
|
||||
};
|
||||
}
|
||||
if (name === "@keyframes") {
|
||||
let pos = end;
|
||||
pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
||||
if (pos === input.length) return pos;
|
||||
const [newPos, name] = eatText(input, pos, eatKeyframes);
|
||||
const { line: sl, column: sc } = locConverter.get(pos);
|
||||
const { line: el, column: ec } = locConverter.get(newPos);
|
||||
const dep = new CssLocalIdentifierDependency(name, [pos, newPos]);
|
||||
dep.setLoc(sl, sc, el, ec);
|
||||
module.addDependency(dep);
|
||||
pos = newPos;
|
||||
if (pos === input.length) return pos;
|
||||
if (input.charCodeAt(pos) !== CC_LEFT_CURLY) {
|
||||
throw new Error(
|
||||
`Unexpected ${input[pos]} at ${pos} during parsing of @keyframes (expected '{')`
|
||||
);
|
||||
}
|
||||
mode = CSS_MODE_IN_LOCAL_RULE;
|
||||
modeNestingLevel = 1;
|
||||
return pos + 1;
|
||||
}
|
||||
return end;
|
||||
},
|
||||
semicolon: (input, start, end) => {
|
||||
switch (mode) {
|
||||
case CSS_MODE_AT_IMPORT_EXPECT_URL:
|
||||
throw new Error(`Expected URL for @import at ${start}`);
|
||||
case CSS_MODE_AT_IMPORT_EXPECT_MEDIA:
|
||||
case CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS: {
|
||||
const { line: sl, column: sc } = locConverter.get(modeData.start);
|
||||
const { line: el, column: ec } = locConverter.get(end);
|
||||
end = eatWhiteLine(input, end);
|
||||
const media = input.slice(modePos, start).trim();
|
||||
const dep = new CssImportDependency(
|
||||
modeData.url,
|
||||
[modeData.start, end],
|
||||
modeData.supports,
|
||||
media
|
||||
);
|
||||
dep.setLoc(sl, sc, el, ec);
|
||||
module.addDependency(dep);
|
||||
break;
|
||||
}
|
||||
case CSS_MODE_IN_LOCAL_RULE: {
|
||||
processDeclarationValueDone(input, start);
|
||||
return processLocalDeclaration(input, end);
|
||||
}
|
||||
case CSS_MODE_IN_RULE: {
|
||||
return end;
|
||||
}
|
||||
}
|
||||
mode = CSS_MODE_TOP_LEVEL;
|
||||
modeData = undefined;
|
||||
singleClassSelector = undefined;
|
||||
return end;
|
||||
},
|
||||
leftCurlyBracket: (input, start, end) => {
|
||||
switch (mode) {
|
||||
case CSS_MODE_TOP_LEVEL:
|
||||
mode = isTopLevelLocal()
|
||||
? CSS_MODE_IN_LOCAL_RULE
|
||||
: CSS_MODE_IN_RULE;
|
||||
modeNestingLevel = 1;
|
||||
if (mode === CSS_MODE_IN_LOCAL_RULE)
|
||||
return processLocalDeclaration(input, end);
|
||||
break;
|
||||
case CSS_MODE_IN_RULE:
|
||||
case CSS_MODE_IN_LOCAL_RULE:
|
||||
modeNestingLevel++;
|
||||
break;
|
||||
}
|
||||
return end;
|
||||
},
|
||||
rightCurlyBracket: (input, start, end) => {
|
||||
switch (mode) {
|
||||
case CSS_MODE_IN_LOCAL_RULE:
|
||||
processDeclarationValueDone(input, start);
|
||||
/* falls through */
|
||||
case CSS_MODE_IN_RULE:
|
||||
if (--modeNestingLevel === 0) {
|
||||
mode = CSS_MODE_TOP_LEVEL;
|
||||
modeData = undefined;
|
||||
singleClassSelector = undefined;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return end;
|
||||
},
|
||||
id: (input, start, end) => {
|
||||
singleClassSelector = false;
|
||||
switch (mode) {
|
||||
case CSS_MODE_TOP_LEVEL:
|
||||
if (isTopLevelLocal()) {
|
||||
const name = input.slice(start + 1, end);
|
||||
const dep = new CssLocalIdentifierDependency(name, [
|
||||
start + 1,
|
||||
end
|
||||
]);
|
||||
const { line: sl, column: sc } = locConverter.get(start);
|
||||
const { line: el, column: ec } = locConverter.get(end);
|
||||
dep.setLoc(sl, sc, el, ec);
|
||||
module.addDependency(dep);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return end;
|
||||
},
|
||||
identifier: (input, start, end) => {
|
||||
singleClassSelector = false;
|
||||
switch (mode) {
|
||||
case CSS_MODE_IN_LOCAL_RULE:
|
||||
if (modeData === "animation") {
|
||||
lastIdentifier = [start, end];
|
||||
}
|
||||
break;
|
||||
}
|
||||
return end;
|
||||
},
|
||||
class: (input, start, end) => {
|
||||
switch (mode) {
|
||||
case CSS_MODE_TOP_LEVEL: {
|
||||
if (isTopLevelLocal()) {
|
||||
const name = input.slice(start + 1, end);
|
||||
const dep = new CssLocalIdentifierDependency(name, [
|
||||
start + 1,
|
||||
end
|
||||
]);
|
||||
const { line: sl, column: sc } = locConverter.get(start);
|
||||
const { line: el, column: ec } = locConverter.get(end);
|
||||
dep.setLoc(sl, sc, el, ec);
|
||||
module.addDependency(dep);
|
||||
if (singleClassSelector === undefined) singleClassSelector = name;
|
||||
} else {
|
||||
singleClassSelector = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return end;
|
||||
},
|
||||
leftParenthesis: (input, start, end) => {
|
||||
switch (mode) {
|
||||
case CSS_MODE_TOP_LEVEL: {
|
||||
modeStack.push(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return end;
|
||||
},
|
||||
rightParenthesis: (input, start, end) => {
|
||||
switch (mode) {
|
||||
case CSS_MODE_TOP_LEVEL: {
|
||||
const newModeData = modeStack.pop();
|
||||
if (newModeData !== false) {
|
||||
modeData = newModeData;
|
||||
const dep = new ConstDependency("", [start, end]);
|
||||
module.addPresentationalDependency(dep);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return end;
|
||||
},
|
||||
pseudoClass: (input, start, end) => {
|
||||
singleClassSelector = false;
|
||||
switch (mode) {
|
||||
case CSS_MODE_TOP_LEVEL: {
|
||||
const name = input.slice(start, end);
|
||||
if (this.allowModeSwitch && name === ":global") {
|
||||
modeData = "global";
|
||||
const dep = new ConstDependency("", [start, end]);
|
||||
module.addPresentationalDependency(dep);
|
||||
} else if (this.allowModeSwitch && name === ":local") {
|
||||
modeData = "local";
|
||||
const dep = new ConstDependency("", [start, end]);
|
||||
module.addPresentationalDependency(dep);
|
||||
} else if (this.allowPseudoBlocks && name === ":export") {
|
||||
const pos = parseExports(input, end);
|
||||
const dep = new ConstDependency("", [start, pos]);
|
||||
module.addPresentationalDependency(dep);
|
||||
return pos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return end;
|
||||
},
|
||||
pseudoFunction: (input, start, end) => {
|
||||
switch (mode) {
|
||||
case CSS_MODE_TOP_LEVEL: {
|
||||
const name = input.slice(start, end - 1);
|
||||
if (this.allowModeSwitch && name === ":global") {
|
||||
modeStack.push(modeData);
|
||||
modeData = "global";
|
||||
const dep = new ConstDependency("", [start, end]);
|
||||
module.addPresentationalDependency(dep);
|
||||
} else if (this.allowModeSwitch && name === ":local") {
|
||||
modeStack.push(modeData);
|
||||
modeData = "local";
|
||||
const dep = new ConstDependency("", [start, end]);
|
||||
module.addPresentationalDependency(dep);
|
||||
} else {
|
||||
modeStack.push(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return end;
|
||||
},
|
||||
function: (input, start, end) => {
|
||||
switch (mode) {
|
||||
case CSS_MODE_IN_LOCAL_RULE: {
|
||||
const name = input.slice(start, end - 1);
|
||||
if (name === "var") {
|
||||
let pos = walkCssTokens.eatWhitespaceAndComments(input, end);
|
||||
if (pos === input.length) return pos;
|
||||
const [newPos, name] = eatText(input, pos, eatNameInVar);
|
||||
if (!name.startsWith("--")) return end;
|
||||
const { line: sl, column: sc } = locConverter.get(pos);
|
||||
const { line: el, column: ec } = locConverter.get(newPos);
|
||||
const dep = new CssSelfLocalIdentifierDependency(
|
||||
name.slice(2),
|
||||
[pos, newPos],
|
||||
"--",
|
||||
declaredCssVariables
|
||||
);
|
||||
dep.setLoc(sl, sc, el, ec);
|
||||
module.addDependency(dep);
|
||||
return newPos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return end;
|
||||
},
|
||||
comma: (input, start, end) => {
|
||||
switch (mode) {
|
||||
case CSS_MODE_TOP_LEVEL:
|
||||
modeData = undefined;
|
||||
modeStack.length = 0;
|
||||
break;
|
||||
case CSS_MODE_IN_LOCAL_RULE:
|
||||
processDeclarationValueDone(input, start);
|
||||
break;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
});
|
||||
|
||||
module.buildInfo.strict = true;
|
||||
module.buildMeta.exportsType = "namespace";
|
||||
module.addDependency(new StaticExportsDependency([], true));
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CssParser;
|
|
@ -0,0 +1,659 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @typedef {Object} CssTokenCallbacks
|
||||
* @property {function(string, number): boolean} isSelector
|
||||
* @property {function(string, number, number, number, number): number=} url
|
||||
* @property {function(string, number, number): number=} string
|
||||
* @property {function(string, number, number): number=} leftParenthesis
|
||||
* @property {function(string, number, number): number=} rightParenthesis
|
||||
* @property {function(string, number, number): number=} pseudoFunction
|
||||
* @property {function(string, number, number): number=} function
|
||||
* @property {function(string, number, number): number=} pseudoClass
|
||||
* @property {function(string, number, number): number=} atKeyword
|
||||
* @property {function(string, number, number): number=} class
|
||||
* @property {function(string, number, number): number=} identifier
|
||||
* @property {function(string, number, number): number=} id
|
||||
* @property {function(string, number, number): number=} leftCurlyBracket
|
||||
* @property {function(string, number, number): number=} rightCurlyBracket
|
||||
* @property {function(string, number, number): number=} semicolon
|
||||
* @property {function(string, number, number): number=} comma
|
||||
*/
|
||||
|
||||
/** @typedef {function(string, number, CssTokenCallbacks): number} CharHandler */
|
||||
|
||||
// spec: https://drafts.csswg.org/css-syntax/
|
||||
|
||||
const CC_LINE_FEED = "\n".charCodeAt(0);
|
||||
const CC_CARRIAGE_RETURN = "\r".charCodeAt(0);
|
||||
const CC_FORM_FEED = "\f".charCodeAt(0);
|
||||
|
||||
const CC_TAB = "\t".charCodeAt(0);
|
||||
const CC_SPACE = " ".charCodeAt(0);
|
||||
|
||||
const CC_SLASH = "/".charCodeAt(0);
|
||||
const CC_BACK_SLASH = "\\".charCodeAt(0);
|
||||
const CC_ASTERISK = "*".charCodeAt(0);
|
||||
|
||||
const CC_LEFT_PARENTHESIS = "(".charCodeAt(0);
|
||||
const CC_RIGHT_PARENTHESIS = ")".charCodeAt(0);
|
||||
const CC_LEFT_CURLY = "{".charCodeAt(0);
|
||||
const CC_RIGHT_CURLY = "}".charCodeAt(0);
|
||||
|
||||
const CC_QUOTATION_MARK = '"'.charCodeAt(0);
|
||||
const CC_APOSTROPHE = "'".charCodeAt(0);
|
||||
|
||||
const CC_FULL_STOP = ".".charCodeAt(0);
|
||||
const CC_COLON = ":".charCodeAt(0);
|
||||
const CC_SEMICOLON = ";".charCodeAt(0);
|
||||
const CC_COMMA = ",".charCodeAt(0);
|
||||
const CC_PERCENTAGE = "%".charCodeAt(0);
|
||||
const CC_AT_SIGN = "@".charCodeAt(0);
|
||||
|
||||
const CC_LOW_LINE = "_".charCodeAt(0);
|
||||
const CC_LOWER_A = "a".charCodeAt(0);
|
||||
const CC_LOWER_U = "u".charCodeAt(0);
|
||||
const CC_LOWER_E = "e".charCodeAt(0);
|
||||
const CC_LOWER_Z = "z".charCodeAt(0);
|
||||
const CC_UPPER_A = "A".charCodeAt(0);
|
||||
const CC_UPPER_E = "E".charCodeAt(0);
|
||||
const CC_UPPER_Z = "Z".charCodeAt(0);
|
||||
const CC_0 = "0".charCodeAt(0);
|
||||
const CC_9 = "9".charCodeAt(0);
|
||||
|
||||
const CC_NUMBER_SIGN = "#".charCodeAt(0);
|
||||
const CC_PLUS_SIGN = "+".charCodeAt(0);
|
||||
const CC_HYPHEN_MINUS = "-".charCodeAt(0);
|
||||
|
||||
const CC_LESS_THAN_SIGN = "<".charCodeAt(0);
|
||||
const CC_GREATER_THAN_SIGN = ">".charCodeAt(0);
|
||||
|
||||
const _isNewLine = cc => {
|
||||
return (
|
||||
cc === CC_LINE_FEED || cc === CC_CARRIAGE_RETURN || cc === CC_FORM_FEED
|
||||
);
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeSpace = (input, pos, callbacks) => {
|
||||
let cc;
|
||||
do {
|
||||
pos++;
|
||||
cc = input.charCodeAt(pos);
|
||||
} while (_isWhiteSpace(cc));
|
||||
return pos;
|
||||
};
|
||||
|
||||
const _isWhiteSpace = cc => {
|
||||
return (
|
||||
cc === CC_LINE_FEED ||
|
||||
cc === CC_CARRIAGE_RETURN ||
|
||||
cc === CC_FORM_FEED ||
|
||||
cc === CC_TAB ||
|
||||
cc === CC_SPACE
|
||||
);
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeSingleCharToken = (input, pos, callbacks) => {
|
||||
return pos + 1;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumePotentialComment = (input, pos, callbacks) => {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
let cc = input.charCodeAt(pos);
|
||||
if (cc !== CC_ASTERISK) return pos;
|
||||
for (;;) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
cc = input.charCodeAt(pos);
|
||||
while (cc === CC_ASTERISK) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
cc = input.charCodeAt(pos);
|
||||
if (cc === CC_SLASH) return pos + 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** @type {function(number): CharHandler} */
|
||||
const consumeString = end => (input, pos, callbacks) => {
|
||||
const start = pos;
|
||||
pos = _consumeString(input, pos, end);
|
||||
if (callbacks.string !== undefined) {
|
||||
pos = callbacks.string(input, start, pos);
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
const _consumeString = (input, pos, end) => {
|
||||
pos++;
|
||||
for (;;) {
|
||||
if (pos === input.length) return pos;
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (cc === end) return pos + 1;
|
||||
if (_isNewLine(cc)) {
|
||||
// bad string
|
||||
return pos;
|
||||
}
|
||||
if (cc === CC_BACK_SLASH) {
|
||||
// we don't need to fully parse the escaped code point
|
||||
// just skip over a potential new line
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
pos++;
|
||||
} else {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const _isIdentifierStartCode = cc => {
|
||||
return (
|
||||
cc === CC_LOW_LINE ||
|
||||
(cc >= CC_LOWER_A && cc <= CC_LOWER_Z) ||
|
||||
(cc >= CC_UPPER_A && cc <= CC_UPPER_Z) ||
|
||||
cc > 0x80
|
||||
);
|
||||
};
|
||||
|
||||
const _isDigit = cc => {
|
||||
return cc >= CC_0 && cc <= CC_9;
|
||||
};
|
||||
|
||||
const _startsIdentifier = (input, pos) => {
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (cc === CC_HYPHEN_MINUS) {
|
||||
if (pos === input.length) return false;
|
||||
const cc = input.charCodeAt(pos + 1);
|
||||
if (cc === CC_HYPHEN_MINUS) return true;
|
||||
if (cc === CC_BACK_SLASH) {
|
||||
const cc = input.charCodeAt(pos + 2);
|
||||
return !_isNewLine(cc);
|
||||
}
|
||||
return _isIdentifierStartCode(cc);
|
||||
}
|
||||
if (cc === CC_BACK_SLASH) {
|
||||
const cc = input.charCodeAt(pos + 1);
|
||||
return !_isNewLine(cc);
|
||||
}
|
||||
return _isIdentifierStartCode(cc);
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeNumberSign = (input, pos, callbacks) => {
|
||||
const start = pos;
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
if (callbacks.isSelector(input, pos) && _startsIdentifier(input, pos)) {
|
||||
pos = _consumeIdentifier(input, pos);
|
||||
if (callbacks.id !== undefined) {
|
||||
return callbacks.id(input, start, pos);
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeMinus = (input, pos, callbacks) => {
|
||||
const start = pos;
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (cc === CC_FULL_STOP || _isDigit(cc)) {
|
||||
return consumeNumericToken(input, pos, callbacks);
|
||||
} else if (cc === CC_HYPHEN_MINUS) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (cc === CC_GREATER_THAN_SIGN) {
|
||||
return pos + 1;
|
||||
} else {
|
||||
pos = _consumeIdentifier(input, pos);
|
||||
if (callbacks.identifier !== undefined) {
|
||||
return callbacks.identifier(input, start, pos);
|
||||
}
|
||||
}
|
||||
} else if (cc === CC_BACK_SLASH) {
|
||||
if (pos + 1 === input.length) return pos;
|
||||
const cc = input.charCodeAt(pos + 1);
|
||||
if (_isNewLine(cc)) return pos;
|
||||
pos = _consumeIdentifier(input, pos);
|
||||
if (callbacks.identifier !== undefined) {
|
||||
return callbacks.identifier(input, start, pos);
|
||||
}
|
||||
} else if (_isIdentifierStartCode(cc)) {
|
||||
pos++;
|
||||
pos = _consumeIdentifier(input, pos);
|
||||
if (callbacks.identifier !== undefined) {
|
||||
return callbacks.identifier(input, start, pos);
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeDot = (input, pos, callbacks) => {
|
||||
const start = pos;
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (_isDigit(cc)) return consumeNumericToken(input, pos - 2, callbacks);
|
||||
if (!callbacks.isSelector(input, pos) || !_startsIdentifier(input, pos))
|
||||
return pos;
|
||||
pos = _consumeIdentifier(input, pos);
|
||||
if (callbacks.class !== undefined) return callbacks.class(input, start, pos);
|
||||
return pos;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeNumericToken = (input, pos, callbacks) => {
|
||||
pos = _consumeNumber(input, pos);
|
||||
if (pos === input.length) return pos;
|
||||
if (_startsIdentifier(input, pos)) return _consumeIdentifier(input, pos);
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (cc === CC_PERCENTAGE) return pos + 1;
|
||||
return pos;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeOtherIdentifier = (input, pos, callbacks) => {
|
||||
const start = pos;
|
||||
pos = _consumeIdentifier(input, pos);
|
||||
if (
|
||||
pos !== input.length &&
|
||||
!callbacks.isSelector(input, pos) &&
|
||||
input.charCodeAt(pos) === CC_LEFT_PARENTHESIS
|
||||
) {
|
||||
pos++;
|
||||
if (callbacks.function !== undefined) {
|
||||
return callbacks.function(input, start, pos);
|
||||
}
|
||||
} else {
|
||||
if (callbacks.identifier !== undefined) {
|
||||
return callbacks.identifier(input, start, pos);
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumePotentialUrl = (input, pos, callbacks) => {
|
||||
const start = pos;
|
||||
pos = _consumeIdentifier(input, pos);
|
||||
if (pos === start + 3 && input.slice(start, pos + 1) === "url(") {
|
||||
pos++;
|
||||
let cc = input.charCodeAt(pos);
|
||||
while (_isWhiteSpace(cc)) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
cc = input.charCodeAt(pos);
|
||||
}
|
||||
if (cc === CC_QUOTATION_MARK || cc === CC_APOSTROPHE) {
|
||||
pos++;
|
||||
const contentStart = pos;
|
||||
pos = _consumeString(input, pos, cc);
|
||||
const contentEnd = pos - 1;
|
||||
cc = input.charCodeAt(pos);
|
||||
while (_isWhiteSpace(cc)) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
cc = input.charCodeAt(pos);
|
||||
}
|
||||
if (cc !== CC_RIGHT_PARENTHESIS) return pos;
|
||||
pos++;
|
||||
if (callbacks.url !== undefined)
|
||||
return callbacks.url(input, start, pos, contentStart, contentEnd);
|
||||
return pos;
|
||||
} else {
|
||||
const contentStart = pos;
|
||||
let contentEnd;
|
||||
for (;;) {
|
||||
if (cc === CC_BACK_SLASH) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
pos++;
|
||||
} else if (_isWhiteSpace(cc)) {
|
||||
contentEnd = pos;
|
||||
do {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
cc = input.charCodeAt(pos);
|
||||
} while (_isWhiteSpace(cc));
|
||||
if (cc !== CC_RIGHT_PARENTHESIS) return pos;
|
||||
pos++;
|
||||
if (callbacks.url !== undefined) {
|
||||
return callbacks.url(input, start, pos, contentStart, contentEnd);
|
||||
}
|
||||
return pos;
|
||||
} else if (cc === CC_RIGHT_PARENTHESIS) {
|
||||
contentEnd = pos;
|
||||
pos++;
|
||||
if (callbacks.url !== undefined) {
|
||||
return callbacks.url(input, start, pos, contentStart, contentEnd);
|
||||
}
|
||||
return pos;
|
||||
} else if (cc === CC_LEFT_PARENTHESIS) {
|
||||
return pos;
|
||||
} else {
|
||||
pos++;
|
||||
}
|
||||
if (pos === input.length) return pos;
|
||||
cc = input.charCodeAt(pos);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (callbacks.identifier !== undefined) {
|
||||
return callbacks.identifier(input, start, pos);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumePotentialPseudo = (input, pos, callbacks) => {
|
||||
const start = pos;
|
||||
pos++;
|
||||
if (!callbacks.isSelector(input, pos) || !_startsIdentifier(input, pos))
|
||||
return pos;
|
||||
pos = _consumeIdentifier(input, pos);
|
||||
let cc = input.charCodeAt(pos);
|
||||
if (cc === CC_LEFT_PARENTHESIS) {
|
||||
pos++;
|
||||
if (callbacks.pseudoFunction !== undefined) {
|
||||
return callbacks.pseudoFunction(input, start, pos);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
if (callbacks.pseudoClass !== undefined) {
|
||||
return callbacks.pseudoClass(input, start, pos);
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeLeftParenthesis = (input, pos, callbacks) => {
|
||||
pos++;
|
||||
if (callbacks.leftParenthesis !== undefined) {
|
||||
return callbacks.leftParenthesis(input, pos - 1, pos);
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeRightParenthesis = (input, pos, callbacks) => {
|
||||
pos++;
|
||||
if (callbacks.rightParenthesis !== undefined) {
|
||||
return callbacks.rightParenthesis(input, pos - 1, pos);
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeLeftCurlyBracket = (input, pos, callbacks) => {
|
||||
pos++;
|
||||
if (callbacks.leftCurlyBracket !== undefined) {
|
||||
return callbacks.leftCurlyBracket(input, pos - 1, pos);
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeRightCurlyBracket = (input, pos, callbacks) => {
|
||||
pos++;
|
||||
if (callbacks.rightCurlyBracket !== undefined) {
|
||||
return callbacks.rightCurlyBracket(input, pos - 1, pos);
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeSemicolon = (input, pos, callbacks) => {
|
||||
pos++;
|
||||
if (callbacks.semicolon !== undefined) {
|
||||
return callbacks.semicolon(input, pos - 1, pos);
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeComma = (input, pos, callbacks) => {
|
||||
pos++;
|
||||
if (callbacks.comma !== undefined) {
|
||||
return callbacks.comma(input, pos - 1, pos);
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
const _consumeIdentifier = (input, pos) => {
|
||||
for (;;) {
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (cc === CC_BACK_SLASH) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
pos++;
|
||||
} else if (
|
||||
_isIdentifierStartCode(cc) ||
|
||||
_isDigit(cc) ||
|
||||
cc === CC_HYPHEN_MINUS
|
||||
) {
|
||||
pos++;
|
||||
} else {
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const _consumeNumber = (input, pos) => {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
let cc = input.charCodeAt(pos);
|
||||
while (_isDigit(cc)) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
cc = input.charCodeAt(pos);
|
||||
}
|
||||
if (cc === CC_FULL_STOP && pos + 1 !== input.length) {
|
||||
const next = input.charCodeAt(pos + 1);
|
||||
if (_isDigit(next)) {
|
||||
pos += 2;
|
||||
cc = input.charCodeAt(pos);
|
||||
while (_isDigit(cc)) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
cc = input.charCodeAt(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cc === CC_LOWER_E || cc === CC_UPPER_E) {
|
||||
if (pos + 1 !== input.length) {
|
||||
const next = input.charCodeAt(pos + 2);
|
||||
if (_isDigit(next)) {
|
||||
pos += 2;
|
||||
} else if (
|
||||
(next === CC_HYPHEN_MINUS || next === CC_PLUS_SIGN) &&
|
||||
pos + 2 !== input.length
|
||||
) {
|
||||
const next = input.charCodeAt(pos + 2);
|
||||
if (_isDigit(next)) {
|
||||
pos += 3;
|
||||
} else {
|
||||
return pos;
|
||||
}
|
||||
} else {
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return pos;
|
||||
}
|
||||
cc = input.charCodeAt(pos);
|
||||
while (_isDigit(cc)) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
cc = input.charCodeAt(pos);
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeLessThan = (input, pos, callbacks) => {
|
||||
if (input.slice(pos + 1, pos + 4) === "!--") return pos + 4;
|
||||
return pos + 1;
|
||||
};
|
||||
|
||||
/** @type {CharHandler} */
|
||||
const consumeAt = (input, pos, callbacks) => {
|
||||
const start = pos;
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
if (_startsIdentifier(input, pos)) {
|
||||
pos = _consumeIdentifier(input, pos);
|
||||
if (callbacks.atKeyword !== undefined) {
|
||||
pos = callbacks.atKeyword(input, start, pos);
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
const CHAR_MAP = Array.from({ length: 0x80 }, (_, cc) => {
|
||||
// https://drafts.csswg.org/css-syntax/#consume-token
|
||||
switch (cc) {
|
||||
case CC_LINE_FEED:
|
||||
case CC_CARRIAGE_RETURN:
|
||||
case CC_FORM_FEED:
|
||||
case CC_TAB:
|
||||
case CC_SPACE:
|
||||
return consumeSpace;
|
||||
case CC_QUOTATION_MARK:
|
||||
case CC_APOSTROPHE:
|
||||
return consumeString(cc);
|
||||
case CC_NUMBER_SIGN:
|
||||
return consumeNumberSign;
|
||||
case CC_SLASH:
|
||||
return consumePotentialComment;
|
||||
// case CC_LEFT_SQUARE:
|
||||
// case CC_RIGHT_SQUARE:
|
||||
// case CC_COMMA:
|
||||
// case CC_COLON:
|
||||
// return consumeSingleCharToken;
|
||||
case CC_COMMA:
|
||||
return consumeComma;
|
||||
case CC_SEMICOLON:
|
||||
return consumeSemicolon;
|
||||
case CC_LEFT_PARENTHESIS:
|
||||
return consumeLeftParenthesis;
|
||||
case CC_RIGHT_PARENTHESIS:
|
||||
return consumeRightParenthesis;
|
||||
case CC_LEFT_CURLY:
|
||||
return consumeLeftCurlyBracket;
|
||||
case CC_RIGHT_CURLY:
|
||||
return consumeRightCurlyBracket;
|
||||
case CC_COLON:
|
||||
return consumePotentialPseudo;
|
||||
case CC_PLUS_SIGN:
|
||||
return consumeNumericToken;
|
||||
case CC_FULL_STOP:
|
||||
return consumeDot;
|
||||
case CC_HYPHEN_MINUS:
|
||||
return consumeMinus;
|
||||
case CC_LESS_THAN_SIGN:
|
||||
return consumeLessThan;
|
||||
case CC_AT_SIGN:
|
||||
return consumeAt;
|
||||
case CC_LOWER_U:
|
||||
return consumePotentialUrl;
|
||||
case CC_LOW_LINE:
|
||||
return consumeOtherIdentifier;
|
||||
default:
|
||||
if (_isDigit(cc)) return consumeNumericToken;
|
||||
if (
|
||||
(cc >= CC_LOWER_A && cc <= CC_LOWER_Z) ||
|
||||
(cc >= CC_UPPER_A && cc <= CC_UPPER_Z)
|
||||
) {
|
||||
return consumeOtherIdentifier;
|
||||
}
|
||||
return consumeSingleCharToken;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {string} input input css
|
||||
* @param {CssTokenCallbacks} callbacks callbacks
|
||||
* @returns {void}
|
||||
*/
|
||||
module.exports = (input, callbacks) => {
|
||||
let pos = 0;
|
||||
while (pos < input.length) {
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (cc < 0x80) {
|
||||
pos = CHAR_MAP[cc](input, pos, callbacks);
|
||||
} else {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.eatComments = (input, pos) => {
|
||||
loop: for (;;) {
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (cc === CC_SLASH) {
|
||||
if (pos === input.length) return pos;
|
||||
let cc = input.charCodeAt(pos + 1);
|
||||
if (cc !== CC_ASTERISK) return pos;
|
||||
pos++;
|
||||
for (;;) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
cc = input.charCodeAt(pos);
|
||||
while (cc === CC_ASTERISK) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
cc = input.charCodeAt(pos);
|
||||
if (cc === CC_SLASH) {
|
||||
pos++;
|
||||
continue loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.eatWhitespaceAndComments = (input, pos) => {
|
||||
loop: for (;;) {
|
||||
const cc = input.charCodeAt(pos);
|
||||
if (cc === CC_SLASH) {
|
||||
if (pos === input.length) return pos;
|
||||
let cc = input.charCodeAt(pos + 1);
|
||||
if (cc !== CC_ASTERISK) return pos;
|
||||
pos++;
|
||||
for (;;) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
cc = input.charCodeAt(pos);
|
||||
while (cc === CC_ASTERISK) {
|
||||
pos++;
|
||||
if (pos === input.length) return pos;
|
||||
cc = input.charCodeAt(pos);
|
||||
if (cc === CC_SLASH) {
|
||||
pos++;
|
||||
continue loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (_isWhiteSpace(cc)) {
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
};
|
|
@ -123,9 +123,7 @@ class Profiler {
|
|||
* @returns {Trace} The trace object
|
||||
*/
|
||||
const createTrace = (fs, outputPath) => {
|
||||
const trace = new Tracer({
|
||||
noStream: true
|
||||
});
|
||||
const trace = new Tracer();
|
||||
const profiler = new Profiler(inspector);
|
||||
if (/\/|\\/.test(outputPath)) {
|
||||
const dirPath = dirname(fs, outputPath);
|
||||
|
@ -173,6 +171,7 @@ const createTrace = (fs, outputPath) => {
|
|||
counter,
|
||||
profiler,
|
||||
end: callback => {
|
||||
trace.push("]");
|
||||
// Wait until the write stream finishes.
|
||||
fsStream.on("close", () => {
|
||||
callback();
|
||||
|
@ -203,15 +202,17 @@ class ProfilingPlugin {
|
|||
|
||||
// Compiler Hooks
|
||||
Object.keys(compiler.hooks).forEach(hookName => {
|
||||
compiler.hooks[hookName].intercept(
|
||||
makeInterceptorFor("Compiler", tracer)(hookName)
|
||||
);
|
||||
const hook = compiler.hooks[hookName];
|
||||
if (hook) {
|
||||
hook.intercept(makeInterceptorFor("Compiler", tracer)(hookName));
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(compiler.resolverFactory.hooks).forEach(hookName => {
|
||||
compiler.resolverFactory.hooks[hookName].intercept(
|
||||
makeInterceptorFor("Resolver", tracer)(hookName)
|
||||
);
|
||||
const hook = compiler.resolverFactory.hooks[hookName];
|
||||
if (hook) {
|
||||
hook.intercept(makeInterceptorFor("Resolver", tracer)(hookName));
|
||||
}
|
||||
});
|
||||
|
||||
compiler.hooks.compilation.tap(
|
||||
|
@ -240,10 +241,10 @@ class ProfilingPlugin {
|
|||
stage: Infinity
|
||||
},
|
||||
(stats, callback) => {
|
||||
if (compiler.watchMode) return callback();
|
||||
tracer.profiler.stopProfiling().then(parsedResults => {
|
||||
if (parsedResults === undefined) {
|
||||
tracer.profiler.destroy();
|
||||
tracer.trace.flush();
|
||||
tracer.end(callback);
|
||||
return;
|
||||
}
|
||||
|
@ -291,7 +292,6 @@ class ProfilingPlugin {
|
|||
});
|
||||
|
||||
tracer.profiler.destroy();
|
||||
tracer.trace.flush();
|
||||
tracer.end(callback);
|
||||
});
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ const interceptAllHooksFor = (instance, tracer, logLabel) => {
|
|||
if (Reflect.has(instance, "hooks")) {
|
||||
Object.keys(instance.hooks).forEach(hookName => {
|
||||
const hook = instance.hooks[hookName];
|
||||
if (!hook._fakeHook) {
|
||||
if (hook && !hook._fakeHook) {
|
||||
hook.intercept(makeInterceptorFor(logLabel, tracer)(hookName));
|
||||
}
|
||||
});
|
||||
|
@ -344,11 +344,15 @@ const interceptAllJavascriptModulesPluginHooks = (compilation, tracer) => {
|
|||
|
||||
const makeInterceptorFor = (instance, tracer) => hookName => ({
|
||||
register: ({ name, type, context, fn }) => {
|
||||
const newFn = makeNewProfiledTapFn(hookName, tracer, {
|
||||
name,
|
||||
type,
|
||||
fn
|
||||
});
|
||||
const newFn =
|
||||
// Don't tap our own hooks to ensure stream can close cleanly
|
||||
name === pluginName
|
||||
? fn
|
||||
: makeNewProfiledTapFn(hookName, tracer, {
|
||||
name,
|
||||
type,
|
||||
fn
|
||||
});
|
||||
return {
|
||||
name,
|
||||
type,
|
||||
|
|
|
@ -90,7 +90,7 @@ AMDRequireDependency.Template = class AMDRequireDependencyTemplate extends (
|
|||
// has array range but no function range
|
||||
if (dep.arrayRange && !dep.functionRange) {
|
||||
const startBlock = `${promise}.then(function() {`;
|
||||
const endBlock = `;}).catch(${RuntimeGlobals.uncaughtErrorHandler})`;
|
||||
const endBlock = `;})['catch'](${RuntimeGlobals.uncaughtErrorHandler})`;
|
||||
runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler);
|
||||
|
||||
source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock);
|
||||
|
@ -103,7 +103,7 @@ AMDRequireDependency.Template = class AMDRequireDependencyTemplate extends (
|
|||
// has function range but no array range
|
||||
if (dep.functionRange && !dep.arrayRange) {
|
||||
const startBlock = `${promise}.then((`;
|
||||
const endBlock = `).bind(exports, __webpack_require__, exports, module)).catch(${RuntimeGlobals.uncaughtErrorHandler})`;
|
||||
const endBlock = `).bind(exports, __webpack_require__, exports, module))['catch'](${RuntimeGlobals.uncaughtErrorHandler})`;
|
||||
runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler);
|
||||
|
||||
source.replace(dep.outerRange[0], dep.functionRange[0] - 1, startBlock);
|
||||
|
@ -118,7 +118,7 @@ AMDRequireDependency.Template = class AMDRequireDependencyTemplate extends (
|
|||
const startBlock = `${promise}.then(function() { `;
|
||||
const errorRangeBlock = `}${
|
||||
dep.functionBindThis ? ".bind(this)" : ""
|
||||
}).catch(`;
|
||||
})['catch'](`;
|
||||
const endBlock = `${dep.errorCallbackBindThis ? ".bind(this)" : ""})`;
|
||||
|
||||
source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock);
|
||||
|
@ -150,9 +150,9 @@ AMDRequireDependency.Template = class AMDRequireDependencyTemplate extends (
|
|||
// has array range, function range, but no errorCallbackRange
|
||||
if (dep.arrayRange && dep.functionRange) {
|
||||
const startBlock = `${promise}.then(function() { `;
|
||||
const endBlock = `}${dep.functionBindThis ? ".bind(this)" : ""}).catch(${
|
||||
RuntimeGlobals.uncaughtErrorHandler
|
||||
})`;
|
||||
const endBlock = `}${
|
||||
dep.functionBindThis ? ".bind(this)" : ""
|
||||
})['catch'](${RuntimeGlobals.uncaughtErrorHandler})`;
|
||||
runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler);
|
||||
|
||||
source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock);
|
||||
|
|
|
@ -117,7 +117,11 @@ CommonJsFullRequireDependency.Template = class CommonJsFullRequireDependencyTemp
|
|||
const comment = equals(usedImported, ids)
|
||||
? ""
|
||||
: Template.toNormalComment(propertyAccess(ids)) + " ";
|
||||
requireExpr += `${comment}${propertyAccess(usedImported)}`;
|
||||
const access = `${comment}${propertyAccess(usedImported)}`;
|
||||
requireExpr =
|
||||
dep.asiSafe === true
|
||||
? `(${requireExpr}${access})`
|
||||
: `${requireExpr}${access}`;
|
||||
}
|
||||
}
|
||||
source.replace(dep.range[0], dep.range[1] - 1, requireExpr);
|
||||
|
|
|
@ -141,7 +141,9 @@ class CommonJsImportsParserPlugin {
|
|||
regExp: options.unknownContextRegExp,
|
||||
mode: "sync"
|
||||
},
|
||||
expr.range
|
||||
expr.range,
|
||||
undefined,
|
||||
parser.scope.inShorthand
|
||||
);
|
||||
dep.critical =
|
||||
options.unknownContextCritical &&
|
||||
|
@ -280,7 +282,7 @@ class CommonJsImportsParserPlugin {
|
|||
dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
|
||||
dep.optional = !!parser.scope.inTry;
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -297,7 +299,7 @@ class CommonJsImportsParserPlugin {
|
|||
dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
|
||||
dep.optional = !!parser.scope.inTry;
|
||||
dep.loc = expr.callee.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
parser.state.current.addDependency(dep);
|
||||
parser.walkExpressions(expr.arguments);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -10,11 +10,13 @@ const ContextDependency = require("./ContextDependency");
|
|||
const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTemplateAsRequireCall");
|
||||
|
||||
class CommonJsRequireContextDependency extends ContextDependency {
|
||||
constructor(options, range, valueRange) {
|
||||
constructor(options, range, valueRange, inShorthand) {
|
||||
super(options);
|
||||
|
||||
this.range = range;
|
||||
this.valueRange = valueRange;
|
||||
// inShorthand must be serialized by subclasses that use it
|
||||
this.inShorthand = inShorthand;
|
||||
}
|
||||
|
||||
get type() {
|
||||
|
@ -26,6 +28,7 @@ class CommonJsRequireContextDependency extends ContextDependency {
|
|||
|
||||
write(this.range);
|
||||
write(this.valueRange);
|
||||
write(this.inShorthand);
|
||||
|
||||
super.serialize(context);
|
||||
}
|
||||
|
@ -35,6 +38,7 @@ class CommonJsRequireContextDependency extends ContextDependency {
|
|||
|
||||
this.range = read();
|
||||
this.valueRange = read();
|
||||
this.inShorthand = read();
|
||||
|
||||
super.deserialize(context);
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ class ContextDependency extends Dependency {
|
|||
this.request = undefined;
|
||||
this.range = undefined;
|
||||
this.valueRange = undefined;
|
||||
this.inShorthand = undefined;
|
||||
// TODO refactor this
|
||||
this.replaces = undefined;
|
||||
}
|
||||
|
|
|
@ -24,13 +24,16 @@ class ContextDependencyTemplateAsRequireCall extends ContextDependency.Template
|
|||
{ runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements }
|
||||
) {
|
||||
const dep = /** @type {ContextDependency} */ (dependency);
|
||||
const moduleExports = runtimeTemplate.moduleExports({
|
||||
let moduleExports = runtimeTemplate.moduleExports({
|
||||
module: moduleGraph.getModule(dep),
|
||||
chunkGraph,
|
||||
request: dep.request,
|
||||
runtimeRequirements
|
||||
});
|
||||
|
||||
if (dep.inShorthand) {
|
||||
moduleExports = `${dep.inShorthand}: ${moduleExports}`;
|
||||
}
|
||||
if (moduleGraph.getModule(dep)) {
|
||||
if (dep.valueRange) {
|
||||
if (Array.isArray(dep.replaces)) {
|
||||
|
|
|
@ -25,6 +25,18 @@ class CreateScriptUrlDependency extends NullDependency {
|
|||
get type() {
|
||||
return "create script url";
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
write(this.range);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
deserialize(context) {
|
||||
const { read } = context;
|
||||
this.range = read();
|
||||
super.deserialize(context);
|
||||
}
|
||||
}
|
||||
|
||||
CreateScriptUrlDependency.Template = class CreateScriptUrlDependencyTemplate extends (
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Ivan Kopeykin @vankop
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const NullDependency = require("./NullDependency");
|
||||
|
||||
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
|
||||
/** @typedef {import("../Dependency")} Dependency */
|
||||
/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
|
||||
/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
|
||||
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
||||
|
||||
class CssExportDependency extends NullDependency {
|
||||
/**
|
||||
* @param {string} name name
|
||||
* @param {string} value value
|
||||
*/
|
||||
constructor(name, value) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "css :export";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exported names
|
||||
* @param {ModuleGraph} moduleGraph module graph
|
||||
* @returns {ExportsSpec | undefined} export names
|
||||
*/
|
||||
getExports(moduleGraph) {
|
||||
const name = this.name;
|
||||
return {
|
||||
exports: [
|
||||
{
|
||||
name,
|
||||
canMangle: true
|
||||
}
|
||||
],
|
||||
dependencies: undefined
|
||||
};
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
write(this.name);
|
||||
write(this.value);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
deserialize(context) {
|
||||
const { read } = context;
|
||||
this.name = read();
|
||||
this.value = read();
|
||||
super.deserialize(context);
|
||||
}
|
||||
}
|
||||
|
||||
CssExportDependency.Template = class CssExportDependencyTemplate extends (
|
||||
NullDependency.Template
|
||||
) {
|
||||
/**
|
||||
* @param {Dependency} dependency the dependency for which the template should be applied
|
||||
* @param {ReplaceSource} source the current replace source which can be modified
|
||||
* @param {DependencyTemplateContext} templateContext the context object
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(dependency, source, { cssExports }) {
|
||||
const dep = /** @type {CssExportDependency} */ (dependency);
|
||||
cssExports.set(dep.name, dep.value);
|
||||
}
|
||||
};
|
||||
|
||||
makeSerializable(
|
||||
CssExportDependency,
|
||||
"webpack/lib/dependencies/CssExportDependency"
|
||||
);
|
||||
|
||||
module.exports = CssExportDependency;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue