Pdfkit: Can't resolve 'fs' in .../...node_modules\pdfkit\js' - webpack loader issue

Created on 3 May 2017  路  16Comments  路  Source: foliojs/pdfkit

My webpack.config.js looks like this:

module.exports = {
    // devtool: 'source-map',
    entry: './src/app.js',
    output: {
        path: path.resolve (__dirname, "dist"),
        filename: "bundle.js"
    },
    module : {
        rules : [
            { test: /\.js$/, loader: 'babel-loader' },
            {
                test : /\.html$/,
                use : [ 'html-loader' ]
            }
        ]
    },
    plugins:
        [ new HtmlWebpackPlugin ({
              template : `src/app.html`
          })
        ]
};

In my app.js i have just this line: - nothing else.
const PDFDocument = require ('pdfkit');
Which gives me the following errors:

ERROR in ./~/pdfkit/js/document.js
Module not found: Error: Can't resolve 'fs' in 'E:\0000 Path..\node_modules\pdfkit\js'
 @ ./~/pdfkit/js/document.js 26:7-20
 @ ./src/app.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 ./src/app.js

ERROR in ./~/pdfkit/js/image.js
Module not found: Error: Can't resolve 'fs' in 'E:\0000 Path...\node_modules\pdfkit\js'
 @ ./~/pdfkit/js/image.js 11:7-20
 @ ./~/pdfkit/js/mixins/images.js
 @ ./~/pdfkit/js/document.js
 @ ./src/app.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 ./src/app.js

I can't get this library working with webpack in any way. Please can you give me an example that uses webpack instead of broweseify?

Most helpful comment

Does anyone know whether PDFKit is compatible with WebPack version 4? The previous solutions do not work anymore ... I'm getting

Can't resolve 'fs'

for pdfkit/js/document.js, pdfkit/js/image.js, pdfkit/js/font/afm.js, png-js/png-node.js.

I have no clue what has changed from WebPack 3 to WebPack 4 ... If anyone has got this working with WebPack 4.0, I'd very much appreciate it.

All 16 comments

@AionDev
any updates on this? Have you succeed to solve it?

@dicbrus i used jsPdf but is not that powerful. Adding:

node: {
  fs: "empty"
}

to my webpack.config.js Didn't work either for me - but do try because lot's of other people say it works..

including the browser releases for pdfkit and blobstream worked for me
https://github.com/devongovett/pdfkit/releases
https://github.com/devongovett/blob-stream/releases

import blobStream from '../libs/blob-stream';
import pdfkit from '../libs/pdfkit';

since they don't rely on fs

I ran into the same problem and adding these 2 loaders into webpack's config solved the problem. Basically they make webpack run all pdfkit-related packages through browserify with the brfs transform (by invoking the transform-loader) and also inline the ./data.json file inside unicode-properties (one of pdfkit's dependencies) (invoking the json-loader). Note that you also need to install the brfs module.

I didn't have to set {node: {fs: 'empty'}}.

{
  module: {
    rules: [
      {
          test: /node_modules\/(pdfkit|fontkit|png-js|linebreak|unicode-properties|brotli)\//,
          loader: "transform-loader?brfs"
      },
      {
        test: /node_modules\/unicode-properties.*\.json$/,
        use: 'json-loader',
      },
    ]
  }
}

@huy-nguyen Thanks for your help here.

Basically they make webpack run all pdfkit-related packages through browserify with the brfs transform

This statement is not accurate. Although brfs was initially designed for browserify it is totally standalone, and we don't need browserify for this. We only require the brfs depenedency and transform-loader for webpack to put it to use.

I actually did a lot of unnecessary research to "solve" this problem because I didn't read your response clearly enough and thought "I don't want browserify running too. That's crazy." But all along the answer was right here. Hahaha.

brfs seems to simply replace occurrences of fs.readFileSync() with the contents of the files they are called to read.

Also a note from transform-loader's readme here about performance. I would think this shouldn't be an issue since we're really only calling transform-loader on pdfkit and some of it's dependencies, but nothing else.

The loader is applied to all JS files, which can incur a performance hit with watch tasks. So you may want to use transform-loader/cacheable?brfs instead.

When I can, I'll try to hunt down the right place in the docs to add this and create a pull request.

{
  module: {
    rules: [
      {
        test: /node_modules\/(pdfkit|fontkit|png-js|linebreak|unicode-properties|brotli)\//,
        loader: "transform-loader?brfs"
      },
      {
        test: /node_modules\/unicode-properties.*\.json$/,
        use: 'json-loader',
      },
    ]
  }
}

@skylize Actually what I posted wasn't enough. This is what I ended up with for webpack loaders config:

[
      {
        // These are all pdfkit-related packages that need to be ran through browserify:
        test: /node_modules\/(pdfkit|png-js|linebreak|unicode-properties|brotli)\//,
        loader: 'transform-loader?brfs',
      },
      // `fontkit` needs special treatment because it needs both `browserify` and `babelify`:
      {
        test: /node_modules\/fontkit\//,
        use: [
          {loader: 'transform-loader?brfs'},
          {
            loader: 'babel-loader',
            options: {
              presets: ['env'],
              plugins: ['transform-decorators-legacy', 'transform-class-properties'],
            },
          },
        ],
      },
      {
        test: /node_modules\/(unicode-properties|fontkit).*\.json$/,
        use: 'json-loader',
      },
]

And I had to set this alias in webpack:

      alias: {
        util$: path.resolve(__dirname, 'node_modules/util'),
      },

And pin down the version of the util package in package.json:

{
    "util": "0.10.0"
}

@huy-nguyen Hmmm. Interesting. I got mine up and running just fine only your first example. But I'm not doing anything special with fonts. I wonder if it matters what features you are using here. ???

Still the comment is incorrect in your newer example. We don't need to "browserify" anything. We only need to handle fs.readFileSync() calls. It is unfortunately confusing that the name brfs is named after browserify, because the tool is in no way dependent on browserify.

It is completely its own small tool that just happened to be initially created to fill a need with browserify. Browserify did not handle calls to fs either. That is why brfs was created.

In case anyone is still confused by the above conversation, I made a minimal example of using webpack and pdfkit.

In my case the solution was to use the approach suggested by Hecklit commented on 9 Aug 2017

@huy-nguyen i'm still getting the fs error, any ideas? I installed your repo, and with node 8 works fine. i'm on node 10, webpack 4.8.2

the repo example doesn't have the babel stuff in your example here, is there something with that?

got it to work with matching versions, thanks! brfs: 1.5.0 worked, but 2.0.0 did not

ok, actually, it starts to try and use fs to load fonts if you specify font(', are there any keywords we can pass into this that wont' trigger it?

For the record I summarize what did the trick for me.
Many thanks to @huy-nguyen for the solution and @kelly-tock for the tip about the brfs version!

I started my project with Vue.js starter project webpack.

In package.json I changed webpack version to 3:

    "webpack": "^3.12.0",

Naturally, I added pdfkit to my dependencies:

    "pdfkit": "^0.8.3",

Then, I added the following devDependencies:

    "transform-loader": "^0.2.4",
    "brfs": "^1.5.0" 

Finally, I fixed the webpack config in the file build/webpack.base.conf.js by adding the following rules to module.rules array:

      {
        test: /node_modules\/(pdfkit|brotli|fontkit|linebreak|png-js|unicode-properties|)\/.*\.js/,
        loader: 'transform-loader?brfs'
      },
      {
        test: /node_modules\/(unicode-properties|fontkit).*\.json$/,
        use: 'json-loader',
      }

In one of my source files I included PDFKit using require:

const PDFDocument = require('pdfkit');

Finally my project built and let me use PDFKit without dirty workarounds! :)

Does anyone know whether PDFKit is compatible with WebPack version 4? The previous solutions do not work anymore ... I'm getting

Can't resolve 'fs'

for pdfkit/js/document.js, pdfkit/js/image.js, pdfkit/js/font/afm.js, png-js/png-node.js.

I have no clue what has changed from WebPack 3 to WebPack 4 ... If anyone has got this working with WebPack 4.0, I'd very much appreciate it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

huy-nguyen picture huy-nguyen  路  4Comments

alFReD-NSH picture alFReD-NSH  路  4Comments

GuiRitter picture GuiRitter  路  3Comments

stephen-last picture stephen-last  路  4Comments

durango picture durango  路  4Comments