diff --git a/.gitignore b/.gitignore index 80e8763..92a1f48 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ .DS_Store npm-debug.log -/node_modules +node_modules fonts/dest* /coverage +.nyc_output +package-lock.json +test/ts/example.js diff --git a/README.md b/README.md index fc4d527..fd8ed76 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,9 @@ $ npm install --save fontmin ## Usage ```js -var Fontmin = require('fontmin'); +import Fontmin from 'fontmin'; -var fontmin = new Fontmin() +const fontmin = new Fontmin() .src('fonts/*.ttf') .dest('build/fonts'); @@ -50,10 +50,10 @@ fontmin.run(function (err, files) { You can use [gulp-rename](https://github.com/hparra/gulp-rename) to rename your files: ```js -var Fontmin = require('fontmin'); -var rename = require('gulp-rename'); +import Fontmin from 'fontmin'; +const rename = require('gulp-rename'); -var fontmin = new Fontmin() +const fontmin = new Fontmin() .src('fonts/big.ttf') .use(rename('small.ttf')); ``` @@ -114,10 +114,10 @@ The following plugins are bundled with fontmin: Compress ttf by glyph. ```js -var Fontmin = require('fontmin'); +import Fontmin from 'fontmin'; -var fontmin = new Fontmin() - .use(Fontmin.glyph({ +const fontmin = new Fontmin() + .use(Fontmin.glyph({ text: '天地玄黄 宇宙洪荒', hinting: false // keep ttf hint info (fpgm, prep, cvt). default = true })); @@ -128,9 +128,9 @@ var fontmin = new Fontmin() Convert ttf to eot. ```js -var Fontmin = require('fontmin'); +import Fontmin from 'fontmin'; -var fontmin = new Fontmin() +const fontmin = new Fontmin() .use(Fontmin.ttf2eot()); ``` @@ -139,9 +139,9 @@ var fontmin = new Fontmin() Convert ttf to woff. ```js -var Fontmin = require('fontmin'); +import Fontmin from 'fontmin'; -var fontmin = new Fontmin() +const fontmin = new Fontmin() .use(Fontmin.ttf2woff({ deflate: true // deflate woff. default = false })); @@ -152,9 +152,9 @@ var fontmin = new Fontmin() Convert ttf to woff2. ```js -var Fontmin = require('fontmin'); +import Fontmin from 'fontmin'; -var fontmin = new Fontmin() +const fontmin = new Fontmin() .use(Fontmin.ttf2woff2()); ``` @@ -165,10 +165,10 @@ Convert ttf to svg. you can use [imagemin-svgo](https://github.com/imagemin/imagemin-svgo) to compress svg: ```js -var Fontmin = require('fontmin'); -var svgo = require('imagemin-svgo'); +import Fontmin from 'fontmin'; +const svgo = require('imagemin-svgo'); -var fontmin = new Fontmin() +const fontmin = new Fontmin() .use(Fontmin.ttf2svg()) .use(svgo()); @@ -179,12 +179,12 @@ var fontmin = new Fontmin() Generate css from ttf, often used to make iconfont. ```js -var Fontmin = require('fontmin'); +import Fontmin from 'fontmin'; -var fontmin = new Fontmin() +const fontmin = new Fontmin() .use(Fontmin.css({ - fontPath: './', // location of font file - base64: true, // inject base64 data:application/x-font-ttf; (gzip font with css). + fontPath: './', // location of font file + base64: true, // inject base64 data:application/x-font-ttf; (gzip font with css). // default = false glyph: true, // generate class for each glyph. default = false iconPrefix: 'my-icon', // class prefix, only work when glyph is `true`. default to "icon" @@ -196,9 +196,9 @@ var fontmin = new Fontmin() Alternatively, a transform function can be passed as `fontFamily` option. ```js -var Fontmin = require('fontmin'); +import Fontmin from 'fontmin'; -var fontmin = new Fontmin() +const fontmin = new Fontmin() .use(Fontmin.css({ // ... fontFamily: function(fontInfo, ttf) { @@ -213,9 +213,9 @@ var fontmin = new Fontmin() Convert font format svg to ttf. ```js -var Fontmin = require('fontmin'); +import Fontmin from 'fontmin'; -var fontmin = new Fontmin() +const fontmin = new Fontmin() .src('font.svg') .use(Fontmin.svg2ttf()); ``` @@ -227,9 +227,9 @@ Concat svg files to a ttf, just like css sprite. awesome work with [css](#css) plugin: ```js -var Fontmin = require('fontmin'); +import Fontmin from 'fontmin'; -var fontmin = new Fontmin() +const fontmin = new Fontmin() .src('svgs/*.svg') .use(Fontmin.svgs2ttf('font.ttf', {fontName: 'iconfont'})) .use(Fontmin.css({ @@ -242,9 +242,9 @@ var fontmin = new Fontmin() Convert otf to ttf. ```js -var Fontmin = require('fontmin'); +import Fontmin from 'fontmin'; -var fontmin = new Fontmin() +const fontmin = new Fontmin() .src('fonts/*.otf') .use(Fontmin.otf2ttf()); ``` diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..0563ac0 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,178 @@ +/** + * @file index.d.ts + * @author kekee000(kekee000@gmail.com) + */ +import through from 'through2'; +import {EventEmitter} from 'events'; +import {Transform} from 'stream'; +import {TTF} from 'fonteditor-core' + +type PluginDesc = (...args: any[]) => Transform; +type InternalPlugin = (opts?: T) => PluginDesc; + +interface GlyphPluginOptions { + /** + * use this text to generate compressed font + */ + text: string; + /** + * add basic chars to glyph + * @example "!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}" + */ + basicText?: boolean; + /** + * keep gylph hinting, defaul true + */ + hinting?: boolean; + /** + * use other plugin + */ + use?: PluginDesc; +} + +interface FontInfo { + fontFile: string; + fontPath: string; + base64: string; + glyph: boolean; + iconPrefix: string; + local: boolean; +} + +interface CssPluginOptions { + /** + *generate class for each glyph. default = false + */ + glyph?: boolean; + /** + * inject base64 data:application/x-font-ttf; (gzip font with css). default = false + */ + base64?: boolean; + /** + * class prefix, only work when glyph is `true`. default to "icon" + */ + iconPrefix?: string; + /** + * rewrite fontFamily as filename force. default = false + */ + asFileName?: boolean; + /** + * location of font file + */ + fontPath?: string; + /** + * custom fontFamily, default to filename or get from analysed ttf file + */ + fontFamily?: string | ((fontInfo: FontInfo, ttf: TTF.TTFObject) => string); + /** + * boolean to add local font. default = false + */ + local?: boolean; +} + +interface Svgs2ttfPluginOptions { + /** + * set font name + */ + fontName?: string; +} + +declare namespace Fontmin { + /* + * get subset font using giving text + */ + const glyph: InternalPlugin; + + /* + * convert ttf to eot + */ + const ttf2eot: InternalPlugin; + + /* + * convert ttf to woff + */ + const ttf2woff: InternalPlugin<{ + /** + * use deflate to transform woff, default false + */ + deflate: boolean; + }>; + + /* + * convert ttf to woff2 + */ + const ttf2woff2: InternalPlugin; + + /* + * convert ttf to svg text + */ + const ttf2svg: InternalPlugin; + + /* + * Generate css from ttf, often used to make iconfont. + */ + const css: InternalPlugin; + + /** + * convert font format svg to ttf + */ + const svg2ttf: InternalPlugin<{hinting?: boolean}>; + + /** + * concat svg files to a ttf, just like css sprite + */ + const svgs2ttf: (file: string, opts?: Svgs2ttfPluginOptions) => through.Through2Constructor; + + /** + * convert otf to ttf + */ + const otf2ttf: InternalPlugin; +} + +type PluginNames = keyof typeof Fontmin; + +declare class Fontmin extends EventEmitter { + static plugins: PluginNames[]; + + /** + * Get or set the source files + * @param file files to be optimized + */ + src(src: ArrayLike | Buffer | string): this; + + /** + * Get or set the destination folder + * @param dir folder to written + */ + dest(dest: string): this; + + /** + * Add a plugin to the middleware stack + * @param plugin plugin function + */ + use(plugin: PluginDesc): this; + + /** + * run Optimize files + * @param callback plugin function + */ + run(callback: (err: Error, files: Buffer[]) => void): Transform; + + /** + * run Optimize files with return Promise + */ + runAsync(): Promise; +} + +export default Fontmin; + +export const mime: { + '.*': 'application/octet-stream', + 'ttf': 'application/font-sfnt', + 'otf': 'application/font-sfnt', + 'woff': 'application/font-woff', + 'woff2': 'application/font-woff2', + 'eot': 'application/octet-stream', + 'svg': 'image/svg+xml', + 'svgz': 'image/svg+xml' +}; diff --git a/index.js b/index.js index 55895f0..fc58b4e 100644 --- a/index.js +++ b/index.js @@ -95,6 +95,22 @@ Fontmin.prototype.run = function (cb) { return stream; }; +/** + * run Optimize files with return Promise + * + * @return {Array} file result + * @api public + */ +Fontmin.prototype.runAsync = function () { + return new Promise((resolve, reject) => { + var stream = this.createStream(); + stream.on('error', reject); + + stream.pipe(concat(resolve)); + }); +}; + + /** * Create stream * @@ -165,5 +181,6 @@ Fontmin.plugins.forEach(function (plugin) { module.exports = Fontmin; // exports util, mime +module.exports.default = Fontmin; module.exports.util = exports.util = require('./lib/util'); module.exports.mime = exports.mime = require('./lib/mime-types'); diff --git a/package.json b/package.json index d2229de..adea5c4 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,9 @@ { "name": "fontmin", - "version": "0.9.9", + "version": "1.0.0", "description": "Minify font seamlessly, font subsetter, webfont (eot, woff, svg) converter.", "main": "index.js", + "types": "index.d.ts", "keywords": [ "font", "webfont", @@ -30,16 +31,22 @@ "license": "MIT", "repository": "ecomfe/fontmin", "engines": { - "node": ">=8" + "node": ">=12" }, "bin": { "fontmin": "cli.js" }, "scripts": { - "test": "mocha", - "coverage": "nyc mocha --reporter spec --check-leaks test/" + "test": "mocha test/*.spec.js", + "coverage": "nyc mocha --reporter spec --check-leaks test/*.spec.js" + }, + "exports": { + "require": "./index.js", + "import": "./index.js" }, "dependencies": { + "@types/node": "^12.20.55", + "@types/through2": "^2.0.38", "b3b": "^0.0.1", "buffer-to-vinyl": "^1.0.0", "code-points": "^2.0.0-1", diff --git a/test/base.js b/test/base.spec.js similarity index 93% rename from test/base.js rename to test/base.spec.js index 0885ad4..4b6636e 100644 --- a/test/base.js +++ b/test/base.spec.js @@ -77,6 +77,13 @@ describe('Fontmin base', function () { }); + it('should run with runAsync', async function () { + const res = await fm() + .src(Buffer.from('')) + .dest(fontPath + '/dest') + .runAsync(); + console.log(res); + }); it('should dest one when clone false', function (done) { diff --git a/test/font.js b/test/font.spec.js similarity index 97% rename from test/font.js rename to test/font.spec.js index dda1e8d..0f127c6 100644 --- a/test/font.js +++ b/test/font.spec.js @@ -78,16 +78,13 @@ before(function (done) { function next() { - fontmin.run(function (err, files, stream) { - - if (err) { - console.log(err); - process.exit(-1); - } - + fontmin.runAsync().then(files => { outputFiles = files; - done(); + }) + .catch (err => { + console.log(err); + process.exit(-1); }); } diff --git a/test/mjs/example.mjs b/test/mjs/example.mjs new file mode 100644 index 0000000..630dc2b --- /dev/null +++ b/test/mjs/example.mjs @@ -0,0 +1,96 @@ +/** + * @file esm example + * @author mengke01(kekee000@gmail.com) + */ +import Fontmin from 'fontmin'; +import rename from 'gulp-rename'; + +{ + const fontmin = new Fontmin() + .src('fonts/*.ttf') + .dest('build/fonts'); + + fontmin.run(function (err, files) { + if (err) { + throw err; + } + + console.log(files[0]); + }); +} +{ + const fontmin = new Fontmin() + .src('fonts/big.ttf') + .use(rename('small.ttf')); +} + +{ + const fontmin = new Fontmin() + .use(Fontmin.glyph({ + text: '天地玄黄 宇宙洪荒', + hinting: false // keep ttf hint info (fpgm, prep, cvt). default = true + })); +} + +{ + const fontmin = new Fontmin() + .use(Fontmin.ttf2eot()); +} +{ + const fontmin = new Fontmin() + .use(Fontmin.ttf2woff({ + deflate: true // deflate woff. default = false + })); +} + +{ + const fontmin = new Fontmin() + .use(Fontmin.ttf2woff2()); +} + + +{ + const fontmin = new Fontmin() + .use(Fontmin.css({ + fontPath: './', // location of font file + base64: true, // inject base64 data:application/x-font-ttf; (gzip font with css). + // default = false + glyph: true, // generate class for each glyph. default = false + iconPrefix: 'my-icon', // class prefix, only work when glyph is `true`. default to "icon" + fontFamily: 'myfont', // custom fontFamily, default to filename or get from analysed ttf file + asFileName: false, // rewrite fontFamily as filename force. default = false + local: true // boolean to add local font. default = false + })); +} + +{ + const fontmin = new Fontmin() + .use(Fontmin.css({ + // ... + fontFamily: function(fontInfo, ttf) { + return "Transformed Font Family Name" + }, + // ... + })); +} + +{ + const fontmin = new Fontmin() + .src('font.svg') + .use(Fontmin.svg2ttf()); +} + +{ + const fontmin = new Fontmin() + .src('svgs/*.svg') + .use(Fontmin.svgs2ttf('font.ttf', {fontName: 'iconfont'})) + .use(Fontmin.css({ + glyph: true + })); +} + +{ + const fontmin = new Fontmin() + .src('fonts/*.otf') + .use(Fontmin.otf2ttf()); +} diff --git a/test/mjs/package.json b/test/mjs/package.json new file mode 100644 index 0000000..a792bd1 --- /dev/null +++ b/test/mjs/package.json @@ -0,0 +1,16 @@ +{ + "name": "mjs", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "node example.mjs" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "fontmin": "file:../../", + "gulp-rename": "^2.0.0" + } +} diff --git a/test/subset.js b/test/subset.spec.js similarity index 100% rename from test/subset.js rename to test/subset.spec.js diff --git a/test/svg2ttf.js b/test/svg2ttf.spec.js similarity index 100% rename from test/svg2ttf.js rename to test/svg2ttf.spec.js diff --git a/test/svgs2ttf.js b/test/svgs2ttf.spec.js similarity index 100% rename from test/svgs2ttf.js rename to test/svgs2ttf.spec.js diff --git a/test/ts/example.ts b/test/ts/example.ts new file mode 100644 index 0000000..e44f765 --- /dev/null +++ b/test/ts/example.ts @@ -0,0 +1,90 @@ +/** + * @file mjs + * @author mengke01(kekee000@gmail.com) + */ +import Fontmin from 'fontmin'; + +{ + const fontmin = new Fontmin() + .src('fonts/*.ttf') + .dest('build/fonts'); + + fontmin.run(function (err, files) { + if (err) { + throw err; + } + + console.log(files[0]); + }); +} + +{ + const fontmin = new Fontmin() + .use(Fontmin.glyph({ + text: '天地玄黄 宇宙洪荒', + hinting: false // keep ttf hint info (fpgm, prep, cvt). default = true + })); +} + +{ + const fontmin = new Fontmin() + .use(Fontmin.ttf2eot()); +} +{ + const fontmin = new Fontmin() + .use(Fontmin.ttf2woff({ + deflate: true // deflate woff. default = false + })); +} + +{ + const fontmin = new Fontmin() + .use(Fontmin.ttf2woff2()); +} + + +{ + const fontmin = new Fontmin() + .use(Fontmin.css({ + fontPath: './', // location of font file + base64: true, // inject base64 data:application/x-font-ttf; (gzip font with css). + // default = false + glyph: true, // generate class for each glyph. default = false + iconPrefix: 'my-icon', // class prefix, only work when glyph is `true`. default to "icon" + fontFamily: 'myfont', // custom fontFamily, default to filename or get from analysed ttf file + asFileName: false, // rewrite fontFamily as filename force. default = false + local: true // boolean to add local font. default = false + })); +} + +{ + const fontmin = new Fontmin() + .use(Fontmin.css({ + // ... + fontFamily: function(fontInfo, ttf) { + return "Transformed Font Family Name" + }, + // ... + })); +} + +{ + const fontmin = new Fontmin() + .src('font.svg') + .use(Fontmin.svg2ttf()); +} + +{ + const fontmin = new Fontmin() + .src('svgs/*.svg') + .use(Fontmin.svgs2ttf('font.ttf', {fontName: 'iconfont'})) + .use(Fontmin.css({ + glyph: true + })); +} + +{ + const fontmin = new Fontmin() + .src('fonts/*.otf') + .use(Fontmin.otf2ttf()); +} diff --git a/test/ts/package.json b/test/ts/package.json new file mode 100644 index 0000000..8a4fa10 --- /dev/null +++ b/test/ts/package.json @@ -0,0 +1,17 @@ +{ + "name": "ts", + "version": "1.0.0", + "description": "", + "main": "example.js", + "scripts": { + "test": "tsc && node example.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "fontmin": "file:../../", + "gulp-rename": "^2.0.0", + "typescript": "^5.1.6" + } +} diff --git a/test/ts/tsconfig.json b/test/ts/tsconfig.json new file mode 100644 index 0000000..d76588f --- /dev/null +++ b/test/ts/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "target": "ES2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ + "module": "commonjs", + "strict": true, /* Enable all strict type-checking options. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + } +}