foliojs / fontkit

An advanced font engine for Node and the browser
1.47k stars 219 forks source link

Proposal for #77 - support using the module in webpack #185

Closed mearns closed 3 years ago

mearns commented 5 years ago

This uses the existing trie generation scripts to also generate a JS module that exports the contents of the trie as a Buffer. This should allow tools like webpack to successfully package fontkit and allow it to be required as a module.

Prior to this, webpack could package it fine, but when the generated bundle executes and tries to import fontkit, it throws an error because of the load-time fs.readFileSync calls.

Pomax commented 5 years ago

Sweet!

mearns commented 5 years ago

Just to be clear, this does not affect the calls to fs.readStream that are used to load fonts from files on the file system; obviously that isn't possible in a browser without some kind of virtual filesystem.

This only affects the unconditional dependencies on the filesystem that occur when the fontkit package is first loaded.

mearns commented 5 years ago

Unfortunately, this doesn't quite work because a dependency, unicode-properties, does the same thing of unconditionally calling fs.readFileSync at load time.

Pomax commented 5 years ago

One solution would be to, rather than trying to have the source "work everywhere", roll up the code for node, and roll up the code with a filesystem shim for the browser, so that people who just want to use fontkit in the browser (but for some reason don't want to use opentype.js?) end up with a thing that works.

mearns commented 5 years ago

Good call @Pomax, I was just wrapping up such a solution for myself yesterday. I don't love it, and imo there's no need to load static data from the filesystem, especially not at module load time, but a filesystem shim serves as an effective work around.

Pomax commented 5 years ago

If the solution feels a little gross, saying "this is how you would do it: ..." in the README.md without actually checking in the code that implements that should work, too.

The important part is usually that people can find the information more than it is making sure that it's been done for them. That way the problem becomes one of "the instructions in the docs don't work" rather than "you say it can be done, but how?"

MRSalomao commented 5 years ago

but for some reason don't want to use opentype.js?

Fontkit has better ligature support than opentype.js:

image (fontkit demo with Pacifico font - https://fontkit-demo.now.sh/)

image (opentype.js demo with Pacifico font - https://opentype.js.org/)

fabianwohlfart commented 5 years ago

Sounds good people. But I am stuck :( Which steps do I have to do to make this work in webpack? – or is browserify mandatory? – or would I need to shim fs with (e.g) BrowserFS? (I got a working browserify build, but now I want to switch to a webpack build) Any help appreciated, thanks!

mearns commented 5 years ago

@fabianwohlfart , I got it working with webpack by putting in a shimfs. I used memfs like this (in src/browser-fs/index.js):

import memfs from 'memfs'
import path from 'path'
import data from './data.trie'
import indic from './indic.trie'
import use from './use.trie'
export * from 'memfs'

memfs.writeFileSync(path.join(__dirname, '/data.trie'), data)
memfs.writeFileSync(path.join(__dirname, '/indic.trie'), indic)
memfs.writeFileSync(path.join(__dirname, '/use.trie'), use)

With the three .trie files copied out of fontkit into the same directory (src/browser-fs/, in my case). I suppose I could have readm those files directly from node_modules/fontkit/, probably would have been a little better.

Then I used this module as my shimfs with the following in my webpack config:

resolve: {
    extensions: ['.js'],
    alias: {
        fs: path.resolve(__dirname, 'src/browser-fs')
    }
}
blikblum commented 5 years ago

You can use transform loader: https://github.com/bpampuch/pdfmake/blob/master/webpack.config.js#L138

privatenumber commented 4 years ago

@devongovett

Possible to get this in?

The fs and data.trie dependencies aren't browser-friendly and seems to require extra setup described here to get it working in a Webpack build.

privatenumber commented 4 years ago

For reference, I also did something similar to @mearns :

fontkit-fs.js

const { Volume } = require('memfs');
const data = require('fontkit/data.trie');
const indic = require('fontkit/indic.trie');
const use = require('fontkit/use.trie');

const fs = new Volume();

fs.writeFileSync('/data.trie', data);
fs.writeFileSync('/indic.trie', indic);
fs.writeFileSync('/use.trie', use);

module.exports = fs;

With the following Webpack config:

{
  modules: {
    rules: [
      {
        test: require.resolve('fontkit'),
        resolve: {
          alias: {
            fs: resolve('./fontkit-fs')
          }
        }
      },
      {
        test: /\.trie$/,
        loader: 'buffer-loader'
      }
    ]
  }
}
Pomax commented 3 years ago

@devongovett @mearns would it be possible to close this PR? It's pretty out of date by now, and I think it's safe to say no one's going to be revisiting it - but, while it's open, it keeps showing up in people's https://github.com/pulls/mentioned queue

mearns commented 3 years ago

Seems like a bad reason to close a PR. Github should support better management of this queue to silence stuff you don't care about. But I'll close this one since clearly the project is abandoned.

howlettga commented 3 years ago

well, wish this PR wasn't closed. Using transform-loader is not an adequate solution, considering it hasn't had support in 4 years. Resolving the fs usage within this package to work with modern webkit would be very nice

blikblum commented 3 years ago

You can try https://www.npmjs.com/package/fontkit-next that removes all dependencies that hardcode fs

Pomax commented 3 years ago

https://www.npmjs.com/package/fontkit and https://www.npmjs.com/package/fontkit-next are the same thing (same repo, same branch even), so that won't do anything.

howlettga commented 3 years ago

Yeah, I don't understand, that link links back to this repository lol. It looks like there are still two files using fs, https://github.com/foliojs/fontkit/blob/master/src/opentype/shapers/ArabicShaper.js and https://github.com/foliojs/fontkit/blob/master/src/opentype/shapers/generate-data.js

will take a look if i have some time