Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pdf.js doesn't work with requirejs #7287

Closed
MartinSnyder opened this issue May 3, 2016 · 18 comments
Closed

pdf.js doesn't work with requirejs #7287

MartinSnyder opened this issue May 3, 2016 · 18 comments

Comments

@MartinSnyder
Copy link

MartinSnyder commented May 3, 2016

The following HTML demonstrates the issue:

<head>
    <title>Flexpaper React/Require Sandbox</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.js"></script>
    <script>
        require(['pdf'], function(pdf) {
            console.log('PDFJS Module: ' + pdf);
            console.log('PDFJS Global: ' + window.PDFJS);
        });
    </script>
</head>
</html>

pdf.js, detects the existence of the "require" and "define" functions and accordingly does NOT set the global PDFJS instance. However, it also does not return a reference to that instance through the module loader.

Because both "pdf" and "window.PDFJS" are undefined in the example above, the library cannot be used in applications that use require. This is the case regardless of whether or not require is used to load pdf.js.

Note that this works correctly with version 1.0.1040 but fails with 1.4.20 and 1.5.188. I did not test with versions other than those 3. The behavior was consistent in all three versions between Chrome and Safari.

@yurydelendik
Copy link
Contributor

what's 'pdf' ? can you provide complete example?

@MartinSnyder
Copy link
Author

Sure, I'll setup a Github repo to demonstrate more fully.

@MartinSnyder
Copy link
Author

Here is the repo: https://github.com/MartinSnyder/pdfjs-with-requirejs

'pdf' is the module reference that require is attempting to return to that function. In that scenario, Requirejs is dynamically loading pdf.js and attempting to return the 'module reference' to the callback function, however the module reference is not set. You can see the dynamic load happen through the browser's network debugger.

This would not be that big a deal normally, except that something inside pdf.js is detecting that a module loader is present and is then NOT setting the global PDFJS object. Since neither is present, you can't use the library when requirejs is on the page.

Note that this happens even if you don't use require to load the object. I put a commented out script reference to pdf.js on the page. If that is placed before require, then the global will be set properly. If that is placed after require, then the global will NOT be set.

@yurydelendik
Copy link
Contributor

yurydelendik commented May 3, 2016

There are two issues with the code:

  1. module is not referred by its name, use 'pdfjs-dist/build/pdf' (and if you are moving pdfjs-dist in different place use require.config to change the location)
  2. you are using document.write, which erases document

Try something like:

        require.config({paths: {'pdfjs-dist': './node_modules/pdfjs-dist'}});
        require(['pdfjs-dist/build/pdf'], function(pdf) {
            console.log('PDFJS Module: ' + pdf + '<br>');
            console.log('PDFJS Global: ' + window.PDFJS);
        });

Closing as answered.

@yurydelendik
Copy link
Contributor

Note that this works correctly with version 1.0.1040

Working at this version is a sideeffect of requirejs loading a script as regular script tag -- does not indicate that it is a compatible with require.js

set the global PDFJS instance

Global PDFJS will be removed in future versions, so if you are using requirejs you can use the same object via pdf.PDFJS/

@MartinSnyder
Copy link
Author

With respect to point 1:
I did not use node to include pdf.js in that example. I downloaded the official distribution and copied pdf.js into the root directory of the sample. For that reason, referencing it as 'pdf' is correct. You can verify this by looking at the example in the network debugger and you will see that the file is correctly downloaded by require.

With respect to point 2:
This was done to simplify the example. Regardless of what the example does, the references are undefined and the library cannot be used. Specifically, switching to console.log also shows the references as undefined.

With respect to Global PDFJS being removed in future versions:
I'm fine with that, but how is one supposed to reference the library via pdf.PDFJS when pdf is undefined?

@yurydelendik
Copy link
Contributor

yurydelendik commented May 3, 2016

I did not use node to include pdf.js in that example

I did not assume you are using node.js.

downloaded the official distribution and copied pdf.js into the root directory of the sample.

PDF.js is a library and consist from many files, e.g. pdfjs-dist/build/pdf module may load pdfjs-dist/build/pdf.worker module

For that reason, referencing it as 'pdf' is correct.

You still need to use AMD name whatever is listed in the define, see https://github.com/MartinSnyder/pdfjs-with-requirejs/blob/master/pdf.js#L21

Did you try the example above with require.config pointing to the complete library?

@MartinSnyder
Copy link
Author

Did you try the example above with require.config pointing to the complete library?

I just completed that now and it works as you said.

Does that mean that you cannot use the "downloaded" distribution found here for this purpose?
https://mozilla.github.io/pdf.js/getting_started/#download

So long as you use the node 'pdfjs-dist' package you are fine, but the downloaded version isn't supposed to work with this?

@yurydelendik
Copy link
Contributor

So long as you use the node 'pdfjs-dist' package you are fine, but the downloaded version isn't supposed to work with this?

I think it's not related to the subject, but you still can use pdf.js/pdf.worker.js files from this package, point requirejs 'pdfjs-dist' to the zipped location (it will work since pdf.js and pdf.worker.js files are located in the build folder).

@MartinSnyder
Copy link
Author

You still need to use AMD name whatever is listed in the define, see https://github.com/MartinSnyder/pdfjs-with-requirejs/blob/master/pdf.js#L21

This was the key bit that I was missing from my understanding. Thank you for taking the time to explain it to me.

@lazzi
Copy link

lazzi commented May 16, 2016

Hi, I have similar issue, so I am not going to open a new one, but ask here, I hope that is alright.
I am trying to implement viewer based on https://github.com/mozilla/pdf.js/blob/master/examples/components/simpleviewer.js using require.js. But when I require both pdf.js and pdf_viewer.js files, PDFJS.PDFViewer is undefined.

Here is sample repo: https://github.com/Lazzi/pdfjs-bower-requirejs

@yurydelendik
Copy link
Contributor

@lazzi your main.js module looks really strange for AMD, try:

define('main', ['pdfjs-dist/build/pdf', 'pdfjs-dist/web/pdf_viewer'], function(pdfjsLib, viewer, require) {

compatibility is not AMD, so I don't know how it will work.

@lazzi
Copy link

lazzi commented May 16, 2016

Yes, it is not AMD, but require.js supports also this kind of module definition: http://requirejs.org/docs/api.html#cjsmodule.

However, your proposed change didn't fix my issue..

@yurydelendik
Copy link
Contributor

@lazzi I see, let's try #7332 (AFAIK AMD name matters)

@lazzi
Copy link

lazzi commented May 16, 2016

@yurydelendik It works! You have been very helpful. Thank you.

@tpietsch
Copy link

tpietsch commented Oct 16, 2016

this may work for you as well being placed in your require.config

    map: {
        '*': {
            'pdfjs-dist/build/pdf.worker' : 'path/to/your/install/pdf.worker'
        }
    },

The map function is essentially a global string replace and the '*' is which dependencies to use the string replace for -- mostly used for including different versions of libs for other libs. Like having 2 versions of JQuery running in parallel. Be careful using -- since it only does string replacement you might end up replacing paths in other dependencies if they match.

The '*' in this case will prob only be the main pdf.js dependency.

@dwaxweiler
Copy link

As I was struggling a bit with correct referencing in RequireJS too, I will leave my solution, which is part of the RequireJS config:

paths: {
    'pdfjs-dist/build/pdf': 'myfolder/pdf.min',
    'pdfjs-dist/build/pdf.worker': 'myfolder/pdf.worker.min'
}

When you do it like that, you do not even have to assign the path to the worker to PDFJS.workerSrc, as suggested in the examples, because the worker will be found automatically.

@allandaly
Copy link

Thank you @dmaxweiler! I struggled with the same issue -- I was having trouble getting pdf.js to load correctly when using RequireJS also. Your solution worked for me! Awesome. Thanks for your help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants