mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-08 19:06:15 -08:00
build(site): [SITE-07] reproduce 41 more console vendor modules
This commit is contained in:
1 parent
b47ede011a
commit
ba1dbd430f
26 files changed
+1163
-24
No files matched your search
@@ -72,8 +72,11 @@ remain SITE-07 / VENDOR-08; this build does not close them. See
|
||||
|
||||
`refactor/baselines/console-feed-provenance.json` maps all 32 modules reachable
|
||||
through relative imports from m6b6 to the official console-feed 3.2.2 archive.
|
||||
Their rebuilt bodies exactly match the frozen bundle. The 68 remaining vendor
|
||||
modules and Parcel wrapper need further provenance; this does not establish a
|
||||
Their rebuilt bodies exactly match the frozen bundle. The separate
|
||||
`console-commonjs-provenance.json` adds 41 exact modules from 13 official archives:
|
||||
React/ReactDOM, scheduler, object-assign, react-is, prop-types, shallowequal,
|
||||
process, hoist-non-react-statics, is-dom/is-object/is-window and linkifyjs.
|
||||
The 27 remaining vendor modules and Parcel wrapper need further provenance; this does not establish a
|
||||
unique original installed version or recover its missing lockfile.
|
||||
|
||||
```sh
|
||||
@@ -82,19 +85,30 @@ node scripts/site-vendor/console/reproduce.ts
|
||||
yarn test:site-console
|
||||
```
|
||||
|
||||
The first command downloads two pinned npm archives into the dedicated ignored
|
||||
The first command downloads 15 pinned npm archives into the dedicated ignored
|
||||
`refactor/.cache/console-feed-reproduction/` directory. The second uses that cache
|
||||
offline. Both verify SHA-512 SRI, archive SHA-256, source member fingerprints,
|
||||
compiler bytes and exact output. They load Terser 3.17.0 as a historical build
|
||||
compiler bytes, original notice bytes and exact output of all 73 identified
|
||||
modules. They load Terser 3.17.0 as a historical build
|
||||
tool with the already installed source-map 0.6.1; they do not install dependencies,
|
||||
change Yarn or execute the archived console-feed runtime. Canonical Node is required.
|
||||
The minification recipe is recovered from Parcel 1.12.5's archive; this proves a
|
||||
reproducing transform, not that the original author used precisely that Parcel
|
||||
version. `provenance.ts` separately verifies complete traversal, relative source
|
||||
mapping and external dependency boundaries. Missing, unreachable, duplicate or
|
||||
changed evidence fails instead of silently shrinking the comparison.
|
||||
changed evidence fails instead of silently shrinking the comparison. Multiple
|
||||
package roots are explicit, relative edges must stay in the same archive, and
|
||||
the remaining module IDs are checked as a complete list. Production entrypoints
|
||||
use the pinned-source process.env.NODE_ENV substitution. The process shim's
|
||||
single process.browser assignment is removed following Parcel's original visitor;
|
||||
this is checked against exact source/output bytes, not a general JS rewrite.
|
||||
|
||||
The archived LICENSE is preserved verbatim with its Facebook attribution under
|
||||
`refactor/baselines/site-vendor/console-feed-3.2.2-LICENSE.txt`. Do not rewrite it
|
||||
or infer it covers every embedded/external component. Complete notices remain
|
||||
open, including the bundled replicator and remaining dependencies.
|
||||
The other 13 archives' LICENSE texts are also frozen under
|
||||
`refactor/baselines/site-vendor/console-commonjs/`, with exact bytes preserved by
|
||||
Git attributes. They are source evidence; complete site notice delivery still
|
||||
requires the remaining component review. React-inspector 5.1.1's CJS file did
|
||||
not match; its ESM conversion remains an investigation, not an accepted source.
|
||||
@@ -4,7 +4,7 @@ import path from 'node:path'
|
||||
import ts from 'typescript'
|
||||
|
||||
export interface Module { id: string, body: string, dependencies: Record<string, string> }
|
||||
export interface Source { id: string, member: string, sourceSha256: string, generatedSha256: string, bodySha256: string }
|
||||
export interface Source { id: string, member: string, sourceSha256: string, generatedSha256: string, bodySha256: string, archive?: string }
|
||||
export interface External { from: string, dependency: string, id: string }
|
||||
export interface Archive { name: string, version: string, tarball: string, integrity: string, sha256: string }
|
||||
export const hash = (bytes: string | Uint8Array) => createHash('sha256').update(bytes).digest('hex')
|
||||
@@ -46,7 +46,7 @@ export function parcelModules(text: string): Map<string, Module> {
|
||||
return result
|
||||
}
|
||||
|
||||
export function verifyModules(modules: Map<string, Module>, sources: Source[], external: External[], read: (member: string) => string, compile: (source: string) => string) {
|
||||
export function verifyModules<S extends Source>(modules: Map<string, Module>, sources: S[], external: External[], read: (member: string, item: S) => string, compile: (source: string, item: S) => string, options = { roots: ['m6b6'], sourcePrefix: 'package/lib/' }) {
|
||||
const mapped = new Map(sources.map(source => [source.id, source]))
|
||||
assert.equal(mapped.size, sources.length, 'Duplicate source mapping')
|
||||
const visited = new Set<string>()
|
||||
@@ -57,11 +57,11 @@ export function verifyModules(modules: Map<string, Module>, sources: Source[], e
|
||||
const item = mapped.get(id)
|
||||
const module = modules.get(id)
|
||||
assert(item && module, `Missing console-feed module mapping: ${id}`)
|
||||
assert(item.member.startsWith('package/lib/') && item.member.endsWith('.js') && path.posix.normalize(item.member) === item.member, 'Invalid source member')
|
||||
assert(item.member.startsWith(options.sourcePrefix) && item.member.endsWith('.js') && path.posix.normalize(item.member) === item.member, 'Invalid source member')
|
||||
visited.add(id)
|
||||
const source = read(item.member)
|
||||
const source = read(item.member, item)
|
||||
assert.equal(hash(source), item.sourceSha256, `Source changed: ${item.member}`)
|
||||
const compiled = compile(source)
|
||||
const compiled = compile(source, item)
|
||||
assert.equal(hash(compiled), item.generatedSha256, `Compiler output changed: ${id}`)
|
||||
assert.equal(hash(module.body), item.bodySha256, `Frozen module changed: ${id}`)
|
||||
assert.equal(compiled, module.body, `Rebuilt module differs: ${id}`)
|
||||
@@ -74,10 +74,12 @@ export function verifyModules(modules: Map<string, Module>, sources: Source[], e
|
||||
const base = path.posix.join(path.posix.dirname(item.member), dependency)
|
||||
const target = mapped.get(child)?.member
|
||||
assert(target && [base, `${base}.js`, `${base}/index.js`].includes(target), `Source dependency mapping changed: ${id} ${dependency}`)
|
||||
assert.equal(item.archive, mapped.get(child)?.archive, `Relative dependency changed archives: ${id} ${dependency}`)
|
||||
visit(child)
|
||||
}
|
||||
}
|
||||
visit('m6b6')
|
||||
assert(options.roots.length && new Set(options.roots).size === options.roots.length, 'Invalid source roots')
|
||||
options.roots.forEach(visit)
|
||||
assert.equal(visited.size, sources.length, 'Unreachable source mapping')
|
||||
assert.deepEqual(dependencies, external, 'External dependency boundary changed')
|
||||
return visited.size
|
||||
|
||||
@@ -8,7 +8,7 @@ import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { hash, parcelModules, verifyArchive, verifyModules } from './provenance.ts'
|
||||
|
||||
interface CompilerOptions { warnings: boolean, safari10: boolean, mangle: { toplevel: boolean } }
|
||||
interface CompilerOptions { warnings: boolean, safari10: boolean, mangle: { toplevel: boolean }, output?: { comments: boolean } }
|
||||
interface Provenance {
|
||||
archive: Archive
|
||||
frozen: { path: string, sha256: string }
|
||||
@@ -17,16 +17,26 @@ interface Provenance {
|
||||
external: External[]
|
||||
}
|
||||
interface Minifier { minify: (source: string, options: CompilerOptions) => { code?: string, error?: unknown } }
|
||||
interface CommonSource extends Source { archive: string, transform: 'plain' | 'production' | 'process-browser' }
|
||||
interface CommonProvenance {
|
||||
archives: (Archive & { id: string, notices: { source: string, member: string, sha256: string }[] })[]
|
||||
sources: CommonSource[]
|
||||
external: External[]
|
||||
roots: string[]
|
||||
compilerOptions: CompilerOptions
|
||||
unresolvedModules: string[]
|
||||
}
|
||||
|
||||
const root = fileURLToPath(new URL('../../../', import.meta.url))
|
||||
const record: Provenance = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/console-feed-provenance.json'), 'utf8'))
|
||||
const common: CommonProvenance = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/console-commonjs-provenance.json'), 'utf8'))
|
||||
assert(process.argv.slice(2).every(arg => arg === '--fetch'), 'Use reproduce.ts [--fetch]')
|
||||
assert.equal(process.version, `v${fs.readFileSync(path.join(root, '.node-version'), 'utf8').trim()}`, 'Use canonical Node')
|
||||
const cacheRoot = fs.realpathSync(path.join(root, 'refactor/.cache'))
|
||||
const cache = path.join(cacheRoot, 'console-feed-reproduction')
|
||||
fs.mkdirSync(cache, { recursive: true })
|
||||
assert.equal(fs.realpathSync(cache), cache, 'Reproduction cache must not redirect')
|
||||
for (const archive of [record.archive, record.compiler.archive]) {
|
||||
for (const archive of [record.archive, record.compiler.archive, ...common.archives]) {
|
||||
const target = path.join(cache, `${archive.name}-${archive.version}.tgz`)
|
||||
if (process.argv.includes('--fetch')) {
|
||||
const response = await fetch(archive.tarball)
|
||||
@@ -50,11 +60,44 @@ const { minify } = require(compilerPath) as Minifier
|
||||
const frozen = fs.readFileSync(path.join(root, record.frozen.path), 'utf8')
|
||||
assert.equal(hash(frozen), record.frozen.sha256, 'Frozen console changed')
|
||||
assert.equal(record.sources.length, 32, 'Incomplete console-feed scope')
|
||||
const count = verifyModules(parcelModules(frozen), record.sources, record.external, member => readMember('console-feed-3.2.2.tgz', member).toString('utf8'), (source) => {
|
||||
const result = minify(source, record.compiler.options)
|
||||
function compile(source: string, options: CompilerOptions) {
|
||||
const result = minify(source, options)
|
||||
if (result.error)
|
||||
throw result.error
|
||||
assert(typeof result.code === 'string')
|
||||
return result.code
|
||||
})
|
||||
console.log(JSON.stringify({ exactModules: count, totalVendorModules: 100, archive: record.archive.sha256, licenseClosure: false }))
|
||||
}
|
||||
const modules = parcelModules(frozen)
|
||||
const count = verifyModules(modules, record.sources, record.external, member => readMember('console-feed-3.2.2.tgz', member).toString('utf8'), source => compile(source, record.compiler.options))
|
||||
assert.equal(common.sources.length, 41, 'Incomplete commonjs scope')
|
||||
const archiveIds = new Set(common.archives.map(archive => archive.id))
|
||||
assert.equal(archiveIds.size, common.archives.length, 'Duplicate archives')
|
||||
for (const archive of common.archives) {
|
||||
assert.equal(archive.id, `${archive.name}-${archive.version}`, 'Archive ID differs')
|
||||
for (const notice of archive.notices) {
|
||||
const bytes = readMember(`${archive.id}.tgz`, notice.member)
|
||||
assert.equal(hash(bytes), notice.sha256, 'Upstream notice differs')
|
||||
assert.equal(hash(fs.readFileSync(path.join(root, notice.source))), notice.sha256, 'Frozen notice differs')
|
||||
}
|
||||
}
|
||||
const commonCount = verifyModules(modules, common.sources, common.external, (member, item) => {
|
||||
assert(archiveIds.has(item.archive), 'Unknown source archive')
|
||||
return readMember(`${item.archive}.tgz`, member).toString('utf8')
|
||||
}, (source, item) => {
|
||||
if (item.transform === 'production') {
|
||||
assert(source.includes('process.env.NODE_ENV'), 'Missing production substitution')
|
||||
source = source.replaceAll('process.env.NODE_ENV', '"production"')
|
||||
}
|
||||
else if (item.transform === 'process-browser') {
|
||||
assert.equal(source.split('process.browser = true;').length, 2, 'Unexpected process browser assignment')
|
||||
source = source.replace('process.browser = true;', '')
|
||||
}
|
||||
else {
|
||||
assert.equal(item.transform, 'plain', 'Unknown transform')
|
||||
}
|
||||
return compile(source, common.compilerOptions)
|
||||
}, { roots: common.roots, sourcePrefix: 'package/' })
|
||||
const identified = new Set([...record.sources, ...common.sources].map(source => source.id))
|
||||
assert.equal(identified.size, count + commonCount, 'Duplicate identified module')
|
||||
assert.deepEqual([...modules.keys()].filter(id => !identified.has(id) && !['Focm', 'W5CS'].includes(id)), common.unresolvedModules, 'Unresolved module scope changed')
|
||||
console.log(JSON.stringify({ exactModules: identified.size, consoleFeed: count, commonjs: commonCount, totalVendorModules: 100, unresolved: common.unresolvedModules.length, licenseClosure: false }))
|
||||
Reference in new issue
Block a user