1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-19 06:38:07 +02:00

Update Webpack to version 5.99.5 (issue 19808)

In Webpack version `5.99.0` the way that `export` statements are handled was changed slightly, with much less boilerplate code being generated, which unfortunately breaks our `tweakWebpackOutput` function that's used to expose the exported properties globally and that e.g. the viewer depends upon.

Given that we were depending on formatting that should most likely be viewed as nothing more than an internal implementation detail in Webpack, we instead work-around this by manually defining the structures that were previously generated.
Obviously this will lead to a tiny bit more manual work in the future, however we don't change the API-surface often enough that it should be a big issue *and* the relevant unit-tests are updated such that it shouldn't be possible to break this.

*NOTE:* In the future we might want to consider no longer using global properties like this, and instead rely only on proper `export`s throughout the code-base.
However changing this would likely be non-trivial (given edge-cases), and it'd be an `api-major` change, so let's just do the minimal amount of work to unblock Webpack updates for now.
This commit is contained in:
Jonas Jenwald 2025-04-13 16:15:07 +02:00
parent c071f44883
commit 6b961c424f
13 changed files with 182 additions and 64 deletions

View file

@ -362,10 +362,6 @@ function createWebpackConfig(
// V8 chokes on very long sequences, work around that.
sequences: false,
},
mangle: {
// Ensure that the `tweakWebpackOutput` function works.
reserved: ["__webpack_exports__"],
},
keep_classnames: true,
keep_fnames: true,
module: isModule,
@ -463,13 +459,6 @@ function checkChromePreferencesFile(chromePrefsPath, webPrefs) {
return ret;
}
function tweakWebpackOutput(jsName) {
return replace(
/((?:\s|,)__webpack_exports__)(?:\s?)=(?:\s?)({};)/gm,
(match, p1, p2) => `${p1} = globalThis.${jsName} = ${p2}`
);
}
function createMainBundle(defines) {
const mainFileConfig = createWebpackConfig(defines, {
filename: defines.MINIFIED ? "pdf.min.mjs" : "pdf.mjs",
@ -479,8 +468,7 @@ function createMainBundle(defines) {
});
return gulp
.src("./src/pdf.js", { encoding: false })
.pipe(webpack2Stream(mainFileConfig))
.pipe(tweakWebpackOutput("pdfjsLib"));
.pipe(webpack2Stream(mainFileConfig));
}
function createScriptingBundle(defines, extraOptions = undefined) {
@ -548,8 +536,7 @@ function createSandboxBundle(defines, extraOptions = undefined) {
return gulp
.src("./src/pdf.sandbox.js", { encoding: false })
.pipe(webpack2Stream(sandboxFileConfig))
.pipe(tweakWebpackOutput("pdfjsSandbox"));
.pipe(webpack2Stream(sandboxFileConfig));
}
function createWorkerBundle(defines) {
@ -561,8 +548,7 @@ function createWorkerBundle(defines) {
});
return gulp
.src("./src/pdf.worker.js", { encoding: false })
.pipe(webpack2Stream(workerFileConfig))
.pipe(tweakWebpackOutput("pdfjsWorker"));
.pipe(webpack2Stream(workerFileConfig));
}
function createWebBundle(defines, options) {
@ -610,8 +596,7 @@ function createComponentsBundle(defines) {
});
return gulp
.src("./web/pdf_viewer.component.js", { encoding: false })
.pipe(webpack2Stream(componentsFileConfig))
.pipe(tweakWebpackOutput("pdfjsViewer"));
.pipe(webpack2Stream(componentsFileConfig));
}
function createImageDecodersBundle(defines) {
@ -625,8 +610,7 @@ function createImageDecodersBundle(defines) {
});
return gulp
.src("./src/pdf.image_decoders.js", { encoding: false })
.pipe(webpack2Stream(componentsFileConfig))
.pipe(tweakWebpackOutput("pdfjsImageDecoders"));
.pipe(webpack2Stream(componentsFileConfig));
}
function createCMapBundle() {

8
package-lock.json generated
View file

@ -58,7 +58,7 @@
"ttest": "^4.0.0",
"typescript": "^5.8.3",
"vinyl": "^3.0.0",
"webpack": "^5.98.0",
"webpack": "^5.99.5",
"webpack-stream": "^7.0.0",
"yargs": "^17.7.2"
},
@ -12388,9 +12388,9 @@
}
},
"node_modules/webpack": {
"version": "5.98.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz",
"integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==",
"version": "5.99.5",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.5.tgz",
"integrity": "sha512-q+vHBa6H9qwBLUlHL4Y7L0L1/LlyBKZtS9FHNCQmtayxjI5RKC9yD8gpvLeqGv5lCQp1Re04yi0MF40pf30Pvg==",
"dev": true,
"license": "MIT",
"dependencies": {

View file

@ -53,7 +53,7 @@
"ttest": "^4.0.0",
"typescript": "^5.8.3",
"vinyl": "^3.0.0",
"webpack": "^5.98.0",
"webpack": "^5.99.5",
"webpack-stream": "^7.0.0",
"yargs": "^17.7.2"
},

View file

@ -2136,6 +2136,13 @@ class PDFWorker {
);
};
}
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
this._resetGlobalState = () => {
this.#isWorkerDisabled = false;
delete globalThis.pdfjsWorker;
};
}
}
constructor({

View file

@ -29,6 +29,18 @@ const pdfjsVersion =
const pdfjsBuild =
typeof PDFJSDev !== "undefined" ? PDFJSDev.eval("BUNDLE_BUILD") : void 0;
globalThis.pdfjsImageDecoders = {
getVerbosityLevel,
Jbig2Error,
Jbig2Image,
JpegError,
JpegImage,
JpxError,
JpxImage,
setVerbosityLevel,
VerbosityLevel,
};
export {
getVerbosityLevel,
Jbig2Error,

View file

@ -93,6 +93,59 @@ if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING || GENERIC")) {
};
}
globalThis.pdfjsLib = {
AbortException,
AnnotationEditorLayer,
AnnotationEditorParamsType,
AnnotationEditorType,
AnnotationEditorUIManager,
AnnotationLayer,
AnnotationMode,
AnnotationType,
build,
ColorPicker,
createValidAbsoluteUrl,
DOMSVGFactory,
DrawLayer,
FeatureTest,
fetchData,
getDocument,
getFilenameFromUrl,
getPdfFilenameFromUrl,
getUuid,
getXfaPageViewport,
GlobalWorkerOptions,
ImageKind,
InvalidPDFException,
isDataScheme,
isPdfFile,
isValidExplicitDest,
MathClamp,
noContextMenu,
normalizeUnicode,
OPS,
OutputScale,
PasswordResponses,
PDFDataRangeTransport,
PDFDateString,
PDFWorker,
PermissionFlag,
PixelsPerInch,
RenderingCancelledException,
ResponseException,
setLayerDimensions,
shadow,
SignatureExtractor,
stopEvent,
SupportedImageMimeTypes,
TextLayer,
TouchManager,
Util,
VerbosityLevel,
version,
XfaLayer,
};
export {
AbortException,
AnnotationEditorLayer,

View file

@ -145,4 +145,8 @@ function QuickJSSandbox() {
return ModuleLoader().then(module => new Sandbox(window, module));
}
globalThis.pdfjsSandbox = {
QuickJSSandbox,
};
export { QuickJSSandbox };

4
src/pdf.worker.js vendored
View file

@ -22,4 +22,8 @@ const pdfjsVersion =
const pdfjsBuild =
typeof PDFJSDev !== "undefined" ? PDFJSDev.eval("BUNDLE_BUILD") : void 0;
globalThis.pdfjsWorker = {
WorkerMessageHandler,
};
export { WorkerMessageHandler };

View file

@ -22,6 +22,18 @@ import { Jbig2Error, Jbig2Image } from "../../src/core/jbig2.js";
import { JpegError, JpegImage } from "../../src/core/jpg.js";
import { JpxError, JpxImage } from "../../src/core/jpx.js";
const expectedAPI = Object.freeze({
getVerbosityLevel,
Jbig2Error,
Jbig2Image,
JpegError,
JpegImage,
JpxError,
JpxImage,
setVerbosityLevel,
VerbosityLevel,
});
describe("pdfimage_api", function () {
it("checks that the *official* PDF.js-image decoders API exposes the expected functionality", async function () {
// eslint-disable-next-line no-unsanitized/method
@ -33,16 +45,10 @@ describe("pdfimage_api", function () {
// The imported Object contains an (automatically) inserted Symbol,
// hence we copy the data to allow using a simple comparison below.
expect({ ...pdfimageAPI }).toEqual({
getVerbosityLevel,
Jbig2Error,
Jbig2Image,
JpegError,
JpegImage,
JpxError,
JpxImage,
setVerbosityLevel,
VerbosityLevel,
});
expect({ ...pdfimageAPI }).toEqual(expectedAPI);
expect(Object.keys(globalThis.pdfjsImageDecoders).sort()).toEqual(
Object.keys(expectedAPI).sort()
);
});
});

View file

@ -13,9 +13,20 @@
* limitations under the License.
*/
import { PDFWorker } from "../../src/display/api.js";
import { WorkerMessageHandler } from "../../src/core/worker.js";
const expectedAPI = Object.freeze({
WorkerMessageHandler,
});
describe("pdfworker_api", function () {
afterEach(function () {
// Avoid interfering with other unit-tests, since `globalThis.pdfjsWorker`
// being defined will impact loading and usage of the worker.
PDFWorker._resetGlobalState();
});
it("checks that the *official* PDF.js-worker API exposes the expected functionality", async function () {
// eslint-disable-next-line no-unsanitized/method
const pdfworkerAPI = await import(
@ -26,8 +37,10 @@ describe("pdfworker_api", function () {
// The imported Object contains an (automatically) inserted Symbol,
// hence we copy the data to allow using a simple comparison below.
expect({ ...pdfworkerAPI }).toEqual({
WorkerMessageHandler,
});
expect({ ...pdfworkerAPI }).toEqual(expectedAPI);
expect(Object.keys(globalThis.pdfjsWorker).sort()).toEqual(
Object.keys(expectedAPI).sort()
);
});
});

View file

@ -135,6 +135,10 @@ describe("pdfjs_api", function () {
// The imported Object contains an (automatically) inserted Symbol,
// hence we copy the data to allow using a simple comparison below.
expect({ ...pdfjsAPI }).toEqual(expectedAPI);
expect(Object.keys(globalThis.pdfjsLib).sort()).toEqual(
Object.keys(expectedAPI).sort()
);
});
});

View file

@ -39,35 +39,41 @@ import { StructTreeLayerBuilder } from "../../web/struct_tree_layer_builder.js";
import { TextLayerBuilder } from "../../web/text_layer_builder.js";
import { XfaLayerBuilder } from "../../web/xfa_layer_builder.js";
const expectedAPI = Object.freeze({
AnnotationLayerBuilder,
DownloadManager,
EventBus,
FindState,
GenericL10n,
LinkTarget,
parseQueryString,
PDFFindController,
PDFHistory,
PDFLinkService,
PDFPageView,
PDFScriptingManager,
PDFSinglePageViewer,
PDFViewer,
ProgressBar,
RenderingStates,
ScrollMode,
SimpleLinkService,
SpreadMode,
StructTreeLayerBuilder,
TextLayerBuilder,
XfaLayerBuilder,
});
describe("pdfviewer_api", function () {
it("checks that the *official* PDF.js-viewer API exposes the expected functionality", async function () {
const pdfviewerAPI = await import("../../web/pdf_viewer.component.js");
// The imported Object contains an (automatically) inserted Symbol,
// hence we copy the data to allow using a simple comparison below.
expect({ ...pdfviewerAPI }).toEqual({
AnnotationLayerBuilder,
DownloadManager,
EventBus,
FindState,
GenericL10n,
LinkTarget,
parseQueryString,
PDFFindController,
PDFHistory,
PDFLinkService,
PDFPageView,
PDFScriptingManager,
PDFSinglePageViewer,
PDFViewer,
ProgressBar,
RenderingStates,
ScrollMode,
SimpleLinkService,
SpreadMode,
StructTreeLayerBuilder,
TextLayerBuilder,
XfaLayerBuilder,
});
expect({ ...pdfviewerAPI }).toEqual(expectedAPI);
expect(Object.keys(globalThis.pdfjsViewer).sort()).toEqual(
Object.keys(expectedAPI).sort()
);
});
});

View file

@ -46,6 +46,31 @@ const pdfjsVersion =
const pdfjsBuild =
typeof PDFJSDev !== "undefined" ? PDFJSDev.eval("BUNDLE_BUILD") : void 0;
globalThis.pdfjsViewer = {
AnnotationLayerBuilder,
DownloadManager,
EventBus,
FindState,
GenericL10n,
LinkTarget,
parseQueryString,
PDFFindController,
PDFHistory,
PDFLinkService,
PDFPageView,
PDFScriptingManager,
PDFSinglePageViewer,
PDFViewer,
ProgressBar,
RenderingStates,
ScrollMode,
SimpleLinkService,
SpreadMode,
StructTreeLayerBuilder,
TextLayerBuilder,
XfaLayerBuilder,
};
export {
AnnotationLayerBuilder,
DownloadManager,