figlet.js icon indicating copy to clipboard operation
figlet.js copied to clipboard

Webpack & TypeScript support

Open Nightbr opened this issue 5 years ago • 9 comments

Hello there, first of all, thanks for this awesome package which enhances all our CLI tool :+1:

Problem Statement

We would like to develop a more robust CLI tool using Webpack & TypeScript. Everything is setup and works properly but I'm running into some errors with figlet integration.

Context

Here is my setup for the project, I will create a boilerplate if needed on Github. But right now, I can share the webpack.config.js:

const path = require('path');

module.exports = {
  mode: 'development',
  entry: './src/index.ts',
  target: 'node',
  stats: {
    warnings: false // /!\ nunjucks as broken import, so webpack log warnings, disabling them for now...
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js']
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
    libraryTarget: 'commonjs'
  }
};

and the tsconfig.json

{
  "compilerOptions": {
    "target": "es2017",
    "module": "commonjs",
    "outDir": "./dist",
    "strict": true,
    "baseUrl": "./src/",
    "typeRoots": ["node_modules/@types"],
    "types": ["node"],
    "esModuleInterop": true,
    "inlineSourceMap": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "resolveJsonModule": true,
    "preserveSymlinks": true
  }
}

But when I want to use figlet there is some errors.

First, with a simple implementation:

import figlet from 'figlet';

console.log(chalk.greenBright(figlet.textSync('plop')));

This will throw an error because webpack doesn't achieve to resolve the fonts folder.

(node:12876) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open '/fonts/Standard.flf'
    at Object.openSync (fs.js:440:3)
    at Object.readFileSync (fs.js:342:35)
    at Function.figlet.loadFontSync (webpack:///./node_modules/figlet/lib/node-figlet.js?:48:23)
    at Object.me.textSync (webpack:///./node_modules/figlet/lib/figlet.js?:732:43)
    at main (webpack:///./src/index.ts?:27:52)
    at Object.eval (webpack:///./src/index.ts?:66:1)
    at eval (webpack:///./src/index.ts?:68:30)

I saw issues about this: #46 & #50 but the node: { __dirname: false } just don't work (or you have to copy the fonts folder at root of your project) & figlet.parseFont has no typing - see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/38318

import figlet from "figlet";
import banner3 from "figlet/importable-fonts/Banner3";

figlet.parseFont("Banner3", banner3);

Add to this, the solution with parseFont is the best I think but you have to declare all importable-fonts in the typing too or you will get this error: If the 'figlet' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/figlet.ts(7016)

import figlet from "figlet";
import banner3 from "figlet/importable-fonts/Banner3";

figlet.parseFont("Banner3", banner3);

Possible Solution

I think we just need to update the typing of figlet on https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/figlet/index.d.ts

  • add parseFont
  • expose importable-fonts as a module

I'm not an expert on module typing with TypeScript that's why I create an issue & not a pull request in order to discuss the best way to create the typing.

Thanks for help :+1:

Nightbr avatar Nov 06 '19 13:11 Nightbr

Hi @Nightbr, as you mentioned, https://github.com/DefinitelyTyped/DefinitelyTyped/issues/38318 has been opened over on DefinitelyTyped for this. However, I don't think it'll be worked unless someone submits a PR.

I'm not really familar with TypeScript, but this is what I think the new file should look like:

https://github.com/patorjk/DefinitelyTyped/blob/figlet_fix/types/figlet/index.d.ts

However, I'm not on a computer where I can run the DefinitelyTyped code. If you want to put in PR for this fix definitely do so. Otherwise if I get some time tonight I'll try and put in a PR with the above branch (all I did for that was put in the line I think is missing).

patorjk avatar Nov 07 '19 15:11 patorjk

Hi @patorjk , How about adding an index.d.ts in the package, would you like a PR?

reezpatel avatar Nov 05 '20 16:11 reezpatel

Hi there. I got a similar error. I'm building a npm package, which should contain figlet. If I test it I get following error: http://localhost:4200/fonts/Standard.flf 404 (Not Found) somehow the npm package does not find the correct font.

index.js file

var figlet = require('figlet');
  figlet('Hello World!!', function(err, data) {
    if (err) {
        console.log('Something went wrong...');
        console.dir(err);
        return;
    }
    console.log(data)
});

Does someone has an idea what I'm doing wrong?

Edit: If I import both figlet and a font like following it works. Is there a method I don't have to import the font seperately? Is it possible to expose all fonts per default?

import figlet from 'figlet';
import standard from 'figlet/importable-fonts/Standard.js'

figlet.parseFont('Standard', standard);

figlet.text('test', {
    font: 'Standard',
}, function(err, data) {
    console.log(data);
});

Yingrjimsch avatar Jan 05 '21 08:01 Yingrjimsch

I would accept a PR.

patorjk avatar Jan 07 '21 01:01 patorjk

Hello,

Until the TypeScript definition on DefinitelyTyped is updated, you can use something like that in your project (inspired from https://github.com/DefinitelyTyped/DefinitelyTyped/issues/38318 and https://github.com/aplr/DefinitelyTyped/commit/099f9bea0641922116078c2421e234e72e3a2cb6):

// src/types/figlet.d.ts

// Extended type definitions for figlet 1.2
// Project: https://github.com/patorjk/figlet.js
// Definitions by: Junyoung Clare Jang <https://github.com/Ailrun>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped

import * as figlet from 'figlet';

declare global {
    export namespace figlet {
        /*
         * Parses data from a FIGlet font file and places it into the figFonts object.
         */
        function parseFont(fontName: string, data: string): FontOptions;

        declare module 'figlet/importable-fonts/*' {
            const value: string;
            export default value;
        }
    }
}

// Important to have this line (even if empty...)
declare module 'figlet' {}

Of course, you'll need to update your TypeScript project configuration to load custom types. For example:

// tsconfig.json

{
  "compilerOptions": {
    (...)
    "typeRoots": [
      "src/types",
      "node_modules/@types"
    ]
  },
}

guicara avatar Feb 22 '21 17:02 guicara

It's 2021, why do we still want to support webpack. Why not just support native ES code and everybody can use it without webpack?

elgs avatar Jul 12 '21 00:07 elgs

@elgs sure thing, make a PR to refactor this lib into a native ES module and it could be bundle with any ES bundler 👌

Nightbr avatar Jul 12 '21 08:07 Nightbr

resolve the problem , thanks

extending avatar Dec 31 '21 08:12 extending

Does this have es support now then?

wujibear avatar Jan 18 '24 15:01 wujibear