ember-auto-import
ember-auto-import copied to clipboard
How to import loader generated chunk file?
This issue is related to ef4/demonstrate-pdfjs#4.
When using prepend feature of fingerprint in production mode (for CDN), it generates a link with http://localhost:4200/assets
string prepended twice in the worker file location. Like this:
http://localhost:4200/assets/http://localhost:4200/assets/bdd7918188e61b7ab667.worker-30c87aa8d07dd8e121d7df9cd499b0f6.js
I did an investigation to find the source of this problem. Pdfjs has a webpack support file. In that file, PdfjsWorker is loaded by worker-loader
in this line:
var PdfjsWorker = require('worker-loader!./build/pdf.worker.js');
This is worker-loader
in inline loading mode. This import creates the problematic link above.
Since inline worker loader creates the problem, I tried to load the worker in my code by worker-loader
configuration:
autoImport: {
webpack: {
module: {
rules: [
{
test: /\.worker\.js$/,
loader: 'worker-loader'
}
]
}
}
}
The loader successfully creates a chunk file of the worker file in the assets directory. Now in my code:
// pdf-viewer.js
....
....
// the codes below resembles pdfjs/webpack.js
let PdfJs = await import('pdfjs-dist/build/pdf');
// need to know this import path
let PdfjsWorker = await import('path-to-worker-chunk-file-created-by-worker-loader');
if (typeof window !== "undefined" && "Worker" in window) {
pdfjs.GlobalWorkerOptions.workerPort = new PdfjsWorker();
}
this.doc = await PdfJs.getDocument(this.documentUrl).promise;
....
....
Now how do I import the chunk file generated by the loader in my code?
If your code, you would say something like await import('pdfjs-dist/build/pdf.worker')
. You always use the unbundled name of the module you want, and let webpack rewrite it to the bundled name.
@ef4 We have to use webpack's worker-loader to import pdf.worker
properly. Without worker-loader
, the code you suggested becomes this:
let PdfJs = await import('pdfjs-dist/build/pdf');
let PdfjsWorker = await import('pdfjs-dist/build/pdf.worker');
if (typeof window !== "undefined" && "Worker" in window) {
pdfjs.GlobalWorkerOptions.workerPort = new PdfjsWorker();
}
this.doc = await PdfJs.getDocument(this.documentUrl).promise;
It creates the following error:
Uncaught (in promise) TypeError: PdfjsWorker is not a constructor
So we have to use worker-loader
. When worker-loader
configuration is set in webpack config, the loader creates its own chunk for the pdf worker. This chunk is created independently of await import. So simple await import won't work for this chunk. I also tried the inline mode of worker-loader but it didn't work.
Right, I was assuming you already have the worker-loader configured in your webpack config.
It seems the real issue here is the double-prepending bug. Are you using broccoli-asset-rev to do the prepending? That is a likely culprit.
Yes. It's a standard Ember app using prepend
of fingerprint config in ember-cli-build.js.
The issue ef4/demonstrate-pdfjs#4 describes the steps to reproduce this problem in your demonstrate-pdfjs
app.
Webpack support file of PdfJs creates a chunk file for pdf-worker with this line.
var PdfjsWorker = require('worker-loader!./build/pdf.worker.js');
This inline mode of worker-loader
appends the following code in the chunk file (Production build, prettified):
function(e, t, r) {
e.exports = function() {
return new Worker(r.p + "http://localhost:4200/assets/bdd7918188e61b7ab667.worker-30c87aa8d07dd8e121d7df9cd499b0f6.js")
}
}
The value of r.p
is http://localhost:4200/assets
and so the double prepend.
We just ran into this issue as well. Following
@musaffa @maartenparmentier did you reach a solution? I'm having issues with loading PDF.js as well.
After adding worker-loader, I had regeneratorRuntime
is undefined. Did you see a similar issue?
Not yet.