Repository: jeerbl/webfonts-loader
Branch: master
Commit: db44b5338a51
Files: 29
Total size: 35.2 KB
Directory structure:
gitextract_2b1_8_c3/
├── .editorconfig
├── .github/
│ ├── FUNDING.yml
│ └── workflows/
│ ├── codeql-analysis.yml
│ ├── codeql.yml
│ ├── dependency-review.yml
│ ├── nodejs-test.yml
│ ├── ossar.yml
│ └── stale.yml
├── .gitignore
├── .npmignore
├── .snyk
├── LICENSE
├── README.md
├── emit-codepoints.js
├── index.js
├── package.json
├── runTest.sh
├── runTestEmbed.sh
├── test/
│ ├── ava.js
│ ├── entry.js
│ ├── myfont.font.js
│ ├── package.json
│ └── webpack.config.js
├── test-embed/
│ ├── ava.js
│ ├── entry.js
│ ├── myfont.font.json
│ ├── package.json
│ └── webpack.config.js
└── utils.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false
[*.sh]
indent_size = 4
================================================
FILE: .github/FUNDING.yml
================================================
github: jeerbl
================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '28 6 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
================================================
FILE: .github/workflows/codeql.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '42 20 * * 4'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
================================================
FILE: .github/workflows/dependency-review.yml
================================================
# Dependency Review Action
#
# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.
#
# Source repository: https://github.com/actions/dependency-review-action
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
name: 'Dependency Review'
on: [pull_request]
permissions:
contents: read
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
uses: actions/checkout@v3
- name: 'Dependency Review'
uses: actions/dependency-review-action@v2
================================================
FILE: .github/workflows/nodejs-test.yml
================================================
name: NodeJS
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Build
run: |
npm install
npm test
================================================
FILE: .github/workflows/ossar.yml
================================================
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow integrates a collection of open source static analysis tools
# with GitHub code scanning. For documentation, or to provide feedback, visit
# https://github.com/github/ossar-action
name: OSSAR
on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '32 5 * * 3'
permissions:
contents: read
jobs:
OSSAR-Scan:
# OSSAR runs on windows-latest.
# ubuntu-latest and macos-latest support coming soon
permissions:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
runs-on: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Ensure a compatible version of dotnet is installed.
# The [Microsoft Security Code Analysis CLI](https://aka.ms/mscadocs) is built with dotnet v3.1.201.
# A version greater than or equal to v3.1.201 of dotnet must be installed on the agent in order to run this action.
# GitHub hosted runners already have a compatible version of dotnet installed and this step may be skipped.
# For self-hosted runners, ensure dotnet version 3.1.201 or later is installed by including this action:
# - name: Install .NET
# uses: actions/setup-dotnet@v2
# with:
# dotnet-version: '3.1.x'
# Run open source static analysis tools
- name: Run OSSAR
uses: github/ossar-action@v1
id: ossar
# Upload results to the Security tab
- name: Upload OSSAR results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: ${{ steps.ossar.outputs.sarifFile }}
================================================
FILE: .github/workflows/stale.yml
================================================
name: Mark stale issues and pull requests
on:
schedule:
- cron: "30 1 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'Stale issue message'
stale-pr-message: 'Stale pull request message'
stale-issue-label: 'no-issue-activity'
stale-pr-label: 'no-pr-activity'
================================================
FILE: .gitignore
================================================
.DS_Store
node_modules/
test/dist/
test-embed/dist/
npm-debug.log
================================================
FILE: .npmignore
================================================
test/*
test-embed/*
================================================
FILE: .snyk
================================================
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
version: v1.14.1
ignore: {}
# patches apply the minimum changes required to fix a vulnerability
patch:
SNYK-JS-LODASH-567746:
- '@vusion/webfonts-generator > svg2ttf > lodash':
patched: '2020-05-01T05:58:26.942Z'
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2017 Jerome Brunel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# webfonts-loader
[](https://www.npmjs.com/package/webfonts-loader)
[](https://www.npmjs.com/package/webfonts-loader)
[](https://github.com/jeerbl/webfonts-loader/actions/workflows/nodejs-test.yml)
[](https://github.com/jeerbl/webfonts-loader/blob/master/LICENSE)
A Webpack loader that generates fonts from your SVG icons and allows you to use your icons in your HTML.
`webfonts-loader` uses the [`webfonts-generator`](https://github.com/vusion/webfonts-generator) plugin to create fonts in any format. It also generates CSS files so that you can use your icons directly in your HTML, using CSS classes.
## Installation
```
npm install webfonts-loader
```
## Usage
An example of usage can be found in the `test/` directory of this repository.
### Webpack rule
Add this rule to your Webpack config:
```javascript
{
test: /\.font\.js/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
url: false
}
},
'webfonts-loader'
]
}
```
So that each font configuration file will be loaded using this rule.
#### Loader options
You can provide `options` objects to configure the loader behaviour:
```javascript
{
test: /\.font\.js/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
url: false
}
},
{
loader: 'webfonts-loader',
options: { ... }
}
]
}
```
Available options are:
##### `publicPath`, String
This is the URL prefix for generated links (e.g. `/static/` or `https://cdn.project.net/`). Should typically match Webpack's `config.output.publicPath`.
##### Any font config option
If you pass `types`, `fileName` or any other font config option, it will be used as a default (unless overriden in font config file).
### The font configuration file
#### Description
The config file allows you to specify parameters for the loader to use. Here is an example configuration file:
```javascript
// myfont.font.js
module.exports = {
'files': [
'./myfont/*.svg'
],
'fontName': 'myfonticons',
'classPrefix': 'myfonticon-',
'baseSelector': '.myfonticon',
'types': ['eot', 'woff2', 'woff', 'ttf', 'svg'],
'fileName': 'app.[fontname].[hash].[ext]'
};
```
Then you have to require the configuration file:
```javascript
// entry.js
require('./myfont.font');
```
The loader will then generate:
* CSS with the base and class prefix
* Font files for the SVG icons
#### All font configuration options
##### `baseSelector`, String
The base CSS selector, under which each icon class is to be created.
See [webfonts-generator#templateOptions](https://github.com/vusion/webfonts-generator#templateoptions)
##### `classPrefix`, String
The prefix to be used with each icon class.
See [webfonts-generator#templateOptions](https://github.com/vusion/webfonts-generator#templateoptions)
##### `cssContext`, Function
Add parameters or helpers to your template.
See [webfonts-generator#cssContext](https://github.com/vusion/webfonts-generator#cssContext)
##### `htmlContext`, Function
Add parameters or helpers to your template.
See [webfonts-generator#htmlContext](https://github.com/vusion/webfonts-generator#htmlContext)
##### `cssTemplate`, String
See [webfonts-generator#cssTemplate](https://github.com/vusion/webfonts-generator#csstemplate)
##### `cssDest`, String
See [webfonts-generator#cssDest](https://github.com/vusion/webfonts-generator#csstemplate)
##### `embed`, Boolean
If true the font is encoded in base64 and embedded inside the `@font-face` declaration, otherwise font files are written to disk.
Default: `false`
##### `scssFile`, Boolean
If true, the build process will export a .scss file in the same path as the .css file.
Default: `false`
##### `hashLength`, Number
Optional. The length of hash in `fileName`.
Min: 8
Max: 32
Default: 20
##### `fileName`, String
The generated font file names. These elements can be used:
* `[fontname]`: the value of the `fontName` parameter
* `[ext]`: the extension of the font file being generated (`eot`, ...)
* `[hash]`: the hash of the current compilation
* `[chunkhash]`: the hash of the SVG files
This option can be also configured globally in the webpack loader options.
##### `emitCodepoints`, Array (with shorthand versions of Boolean, String and Object)
Optional. The generated codepoints file names.
Examples:
* `emitCodepoints: true`: emits a javascript file named `[fontname].codepoints.js` in the `web` (default) format
* `emitCodepoints: '[fontname].codepoints.fonts.js'`: emits a javascript file named `[fontname].codepoints.fonts.js` in the `commonjs` format
* `emitCodepoints: { fileName: '[fontname].codepoints.json', type: 'json'] }`: emits a file named `[fontname].codepoints.json` in the `json` format
* `emitCodepoints: [{ fileName: '[fontname].codepoints.json', type: 'json'] }, { fileName: '[fontname].codepoints.js', type: 'web'] }, { fileName: '[fontname].codepoints.inc.js', type: 'web'] }]`: emits three files with their respective names and types
These are the existing formats:
* `web`: (default): generates a file containing the array of codepoints in a format suitable for inclusion in html pages.
Example (for a font named myfonticons):
```javascript
if (typeof webfontIconCodepoints === 'undefined') {
webfontIconCodepoints = {};
}
webfontIconCodepoints["myfonticons"] = {"alert":61697,"arrow-down":61698,"arrow-left":61699};
```
* `commonjs`: generates a file containing the array of codepoints in the commonjs format, for use with `require`.
```javascript
module.exports = {"alert":61697,"arrow-down":61698,"arrow-left":61699}
```
* `json`: generates a file containing the array of codepoints in the JSON format.
```javascript
{"alert":61697,"arrow-down":61698,"arrow-left":61699,"arrow-right":61700,"arrow-small-down":61701}
```
These elements can be used in the filename:
* `[fontname]`: the value of the `fontName` parameter
* `[chunkhash]`: the hash of the SVG files
This option can be also configured globally in the webpack loader options.
##### `files`, Array
See [webfonts-generator#files](https://github.com/vusion/webfonts-generator#files)
##### `fontName`, String
See [webfonts-generator#fontname](https://github.com/vusion/webfonts-generator#fontname)
##### `formatOptions`, Object
See [webfonts-generator#formatoptions](https://github.com/vusion/webfonts-generator#formatoptions)
##### `rename`, Function
See [webfonts-generator#rename](https://github.com/vusion/webfonts-generator#rename)
##### `types`, Array<String>
See [webfonts-generator#types](https://github.com/vusion/webfonts-generator#types)
##### `dest`, String
See [webfonts-generator#dest](https://github.com/vusion/webfonts-generator#dest)
##### `html`, Boolean
See [webfonts-generator#html](https://github.com/vusion/webfonts-generator#html)
##### `htmlDest`, String
See [webfonts-generator#htmldest](https://github.com/vusion/webfonts-generator#htmldest)
##### `ligature`, Boolean
See [webfonts-generator#ligature](https://github.com/vusion/webfonts-generator#ligature)
##### `cssFontsUrl`, String (before cssFontsPath)
See [webfonts-generator#cssfontspath](https://github.com/vusion/webfonts-generator#cssfontspath)
##### `htmlTemplate`, String
#### Example
```
...
htmlTemplate: path.resolve(__dirname, 'src/html.hbs'),
...
```
See [webfonts-generator#htmltemplate](https://github.com/vusion/webfonts-generator#htmltemplate)
##### `startCodepoint`, Number
See [webfonts-generator#startcodepoint](https://github.com/vusion/webfonts-generator#startcodepoint)
================================================
FILE: emit-codepoints.js
================================================
var loaderUtils = require('loader-utils');
var hashFiles = require('./utils').hashFiles;
module.exports = {
createArrayCodepointFiles (codepointFiles, elem) {
const defaultElem = { fileName: '[fontname].codepoints.js', type: 'web' };
if (typeof (elem) === 'boolean') {
codepointFiles.push(Object.assign({}, defaultElem));
} else if (typeof (elem) === 'string') {
codepointFiles.push(Object.assign({}, defaultElem, { fileName: elem }));
} else if (Array.isArray(elem)) {
elem.forEach(e => this.createArrayCodepointFiles(codepointFiles, e));
} else if (typeof (elem) === 'object') {
codepointFiles.push(Object.assign({}, defaultElem, elem));
}
},
emitFiles (loaderContext, emitCodepointsOptions, generatorOptions, options) {
var codepointFiles = [];
this.createArrayCodepointFiles(codepointFiles, emitCodepointsOptions);
codepointFiles.forEach(emitOption => {
var codepointsContent = JSON.stringify(generatorOptions.codepoints);
switch (emitOption.type) {
case 'commonjs': {
codepointsContent = 'module.exports = ' + codepointsContent + ';';
break;
}
case 'web': {
codepointsContent = [
'if (typeof webfontIconCodepoints === \'undefined\') {',
' webfontIconCodepoints = {};',
'}',
'webfontIconCodepoints[' + JSON.stringify(generatorOptions.fontName) + '] = ' + codepointsContent + ';'
].join('\n');
break;
}
case 'json': {
break;
}
}
var codepointsFilename = emitOption.fileName;
var chunkHash = codepointsFilename.indexOf('[chunkhash]') !== -1
? hashFiles(generatorOptions.files, options.hashLength) : '';
codepointsFilename = codepointsFilename
.replace('[chunkhash]', chunkHash)
.replace('[fontname]', generatorOptions.fontName);
codepointsFilename = loaderUtils.interpolateName(loaderContext,
codepointsFilename,
{
context: loaderContext.rootContext || loaderContext.options.context || loaderContext.context,
content: codepointsContent
}
);
loaderContext.emitFile(codepointsFilename, codepointsContent);
});
}
};
================================================
FILE: index.js
================================================
var loaderUtils = require('loader-utils');
var webfontsGenerator = require('@vusion/webfonts-generator');
var path = require('path');
var glob = require('glob');
var url = require('url');
var hashFiles = require('./utils').hashFiles;
var NativeModule = require('module');
var mimeTypes = {
'eot': 'application/vnd.ms-fontobject',
'svg': 'image/svg+xml',
'ttf': 'application/x-font-ttf',
'woff': 'application/font-woff',
'woff2': 'font/woff2'
};
function getFilesAndDeps (patterns, context) {
var files = [];
var filesDeps = [];
var directoryDeps = [];
function addFile (file) {
filesDeps.push(file);
files.push(path.resolve(context, file));
}
function addByGlob (globExp) {
var globOptions = {
cwd: context
};
var foundFiles = glob.sync(globExp, globOptions);
files = files.concat(foundFiles.map(file => {
return path.resolve(context, file);
}));
var globDirs = glob.sync(path.dirname(globExp) + '/', globOptions);
directoryDeps = directoryDeps.concat(globDirs.map(file => {
return path.resolve(context, file);
}));
}
// Re-work the files array.
patterns.forEach(function (pattern) {
if (glob.hasMagic(pattern)) {
addByGlob(pattern);
} else {
addFile(pattern);
}
});
return {
files: files,
dependencies: {
directories: directoryDeps,
files: filesDeps
}
};
}
// Futureproof webpack option parsing
function wpGetOptions (context) {
if (typeof context.query === 'string') return loaderUtils.getOptions(context);
return context.query;
}
module.exports = function (content) {
this.cacheable();
var options = wpGetOptions(this) || {};
var rawFontConfig;
try {
rawFontConfig = JSON.parse(content);
} catch (ex) {
var module = new NativeModule(this.resourcePath);
module.paths = NativeModule._nodeModulePaths(this.context);
module.filename = this.resourcePath;
module._compile(content, this.resourcePath);
rawFontConfig = module.exports;
}
var fontConfig = Object.assign({}, options, rawFontConfig);
var filesAndDeps = getFilesAndDeps(fontConfig.files, this.context);
filesAndDeps.dependencies.files.forEach(this.addDependency.bind(this));
filesAndDeps.dependencies.directories.forEach(this.addContextDependency.bind(this));
fontConfig.files = filesAndDeps.files;
// With everything set up, let's make an ACTUAL config.
var formats = fontConfig.types || ['eot', 'woff2', 'woff', 'ttf', 'svg'];
if (formats.constructor !== Array) {
formats = [formats];
}
var generatorOptions = {
files: fontConfig.files,
fontName: fontConfig.fontName,
types: formats,
order: formats,
fontHeight: fontConfig.fontHeight || 1000, // Fixes conversion issues with small svgs,
codepoints: fontConfig.codepoints || {},
templateOptions: {
baseSelector: fontConfig.baseSelector || '.icon',
classPrefix: 'classPrefix' in fontConfig ? fontConfig.classPrefix : 'icon-'
},
scssFile: fontConfig.scssFile || false,
dest: fontConfig.dest || '',
html: fontConfig.html || false,
htmlDest: fontConfig.htmlDest || undefined,
cssDest: fontConfig.cssDest ? path.resolve(this.context, fontConfig.cssDest, fontConfig.fontName.toLowerCase() + '.css') : undefined,
cssFontsUrl: fontConfig.cssFontsUrl || '',
embed: fontConfig.embed || false,
formatOptions: fontConfig.formatOptions || {},
writeFiles: false
};
if ('startCodepoint' in fontConfig) generatorOptions.startCodepoint = fontConfig.startCodepoint;
if ('ligature' in fontConfig) generatorOptions.ligature = fontConfig.ligature;
if ('htmlTemplate' in fontConfig) generatorOptions.htmlTemplate = fontConfig.htmlTemplate;
// This originally was in the object notation itself.
// Unfortunately that actually broke my editor's syntax-highlighting...
// ... what a shame.
if (typeof fontConfig.rename === 'function') {
generatorOptions.rename = fontConfig.rename;
} else {
generatorOptions.rename = function (f) {
return path.basename(f, '.svg');
};
}
if (fontConfig.cssContext) {
generatorOptions.cssContext = fontConfig.cssContext;
}
if (fontConfig.htmlContext) {
generatorOptions.htmlContext = fontConfig.htmlContext;
}
if (fontConfig.cssTemplate) {
generatorOptions.cssTemplate = path.resolve(this.context, fontConfig.cssTemplate);
}
if (fontConfig.cssFontsUrl) {
generatorOptions.cssFontsUrl = path.resolve(this.context, fontConfig.cssFontsUrl);
}
if (fontConfig.htmlTemplate) {
generatorOptions.htmlTemplate = path.resolve(this.context, fontConfig.htmlTemplate);
}
if (fontConfig.htmlDest) {
generatorOptions.htmlDest = path.resolve(this.context, fontConfig.htmlDest);
}
if (fontConfig.dest) {
if (fontConfig.dest.endsWith('/')) {
generatorOptions.dest = fontConfig.dest;
} else {
generatorOptions.dest = `${fontConfig.dest}/`;
}
}
// Spit out SCSS file to same path as CSS file to easily use mixins (scssFile must be true)
if (fontConfig.cssDest && fontConfig.scssFile) {
generatorOptions.cssDest = path.resolve(this.context, fontConfig.cssDest, fontConfig.fontName.toLowerCase() + '.scss');
}
// svgicons2svgfont stuff
var keys = [
'fixedWidth',
'centerHorizontally',
'normalize',
'fontHeight',
'round',
'descent'
];
for (var x in keys) {
if (typeof fontConfig[keys[x]] !== 'undefined') {
generatorOptions[keys[x]] = fontConfig[keys[x]];
}
}
var cb = this.async();
var publicPath;
if (typeof options.publicPath === 'string') {
if (options.publicPath === '' || options.publicPath.endsWith('/')) {
publicPath = options.publicPath;
} else {
publicPath = `${options.publicPath}/`;
}
} else {
if (typeof options.publicPath === 'function') {
publicPath = options.publicPath(this.resourcePath, this.rootContext);
} else {
publicPath = this._compilation.outputOptions.publicPath || '/';
}
}
var embed = !!generatorOptions.embed;
if (generatorOptions.cssTemplate) {
this.addDependency(generatorOptions.cssTemplate);
}
if (generatorOptions.cssFontsUrl) {
this.addDependency(generatorOptions.cssFontsUrl);
}
webfontsGenerator(generatorOptions, (err, res) => {
if (err) {
return cb(err);
}
var urls = {};
for (var i in formats) {
var format = formats[i];
var filename = fontConfig.fileName || options.fileName || '[chunkhash]-[fontname].[ext]';
var chunkHash = filename.indexOf('[chunkhash]') !== -1
? hashFiles(generatorOptions.files, options.hashLength) : '';
filename = generatorOptions.dest.concat(filename);
filename = filename
.replace('[chunkhash]', chunkHash)
.replace('[fontname]', generatorOptions.fontName)
.replace('[ext]', format);
if (!embed) {
var formatFilename = loaderUtils.interpolateName(this,
filename,
{
context: this.rootContext || this.options.context || this.context,
content: res[format]
}
);
urls[format] = url.resolve(publicPath, formatFilename.replace(/\\/g, '/'));
this.emitFile(formatFilename, res[format]);
} else {
urls[format] = 'data:' +
mimeTypes[format] +
';charset=utf-8;base64,' +
(Buffer.from(res[format]).toString('base64'));
}
}
var emitCodepointsOptions = fontConfig.emitCodepoints || options.emitCodepoints || null;
if (emitCodepointsOptions) {
var emitCodepoints = require('./emit-codepoints');
emitCodepoints.emitFiles(this, emitCodepointsOptions, generatorOptions, options);
}
if (generatorOptions.html) {
var htmlDest = generatorOptions.htmlDest ? generatorOptions.htmlDest : generatorOptions.fontName + '.html';
htmlDest = generatorOptions.dest.concat(htmlDest);
htmlDest = loaderUtils.interpolateName(this,
htmlDest,
{
context: this.rootContext || this.options.context || this.context
}
);
var relativeUrls = {};
for (var key in urls) {
relativeUrls[key] = path.relative(url.resolve(publicPath, path.dirname(htmlDest.replace(/\\/g, '/'))), urls[key]);
}
var htmlContent = res.generateHtml(relativeUrls);
this.emitFile(htmlDest, htmlContent);
}
cb(null, res.generateCss(urls));
});
};
================================================
FILE: package.json
================================================
{
"name": "webfonts-loader",
"version": "8.1.1",
"description": "A WebPack loader to automatically generate font files and CSS to make your own icon font",
"repository": "jeerbl/webfonts-loader",
"main": "index.js",
"scripts": {
"test": "semistandard && ./runTest.sh && ./runTestEmbed.sh",
"snyk-protect": "snyk protect",
"prepare": "npm run snyk-protect"
},
"keywords": [
"font",
"webfont",
"iconfont",
"web",
"icon",
"generator",
"webpack",
"loader"
],
"author": "Jérôme",
"funding": {
"url": "https://github.com/sponsors/jeerbl"
},
"license": "MIT",
"dependencies": {
"@vusion/webfonts-generator": "^0.8.0",
"glob": "^7.1.6",
"loader-utils": "^2.0.0"
},
"devDependencies": {
"semistandard": "^13.0.1",
"snyk": "^1.461.0"
},
"semistandard": {
"ignore": [
"**/node_modules/"
]
},
"snyk": true
}
================================================
FILE: runTest.sh
================================================
#!/bin/sh
cd test && npm install && npm test
================================================
FILE: runTestEmbed.sh
================================================
#!/bin/sh
cd test-embed && npm install && npm test
================================================
FILE: test/ava.js
================================================
var test = require('ava');
var glob = require('glob').sync;
var hashFiles = require('../utils').hashFiles;
test('check consistency of files hash without hash length option', function (t) {
var files = glob('./test/test-svg/*.svg');
var expected = 'da39a3ee5e6b4b0d3255';
t.is(hashFiles(files), expected);
});
test('check consistency of files hash with min hash length option', function (t) {
var files = glob('./test/test-svg/*.svg');
var expected = 'da39a3ee';
var minHashLength = 8;
t.is(hashFiles(files, minHashLength), expected);
});
test('check consistency of files hash with max hash length option', function (t) {
var files = glob('./test/test-svg/*.svg');
var expected = 'da39a3ee5e6b4b0d3255bfef95601890';
var maxHashLength = 32;
t.is(hashFiles(files, maxHashLength), expected);
});
================================================
FILE: test/entry.js
================================================
require('./myfont.font');
================================================
FILE: test/myfont.font.js
================================================
module.exports = {
'files': [
'./test-svg/*.svg'
],
'fontName': 'myfonticons',
'classPrefix': 'myfonticon-',
'baseSelector': '.myfonticon',
'types': ['eot', 'woff2', 'woff', 'ttf', 'svg'],
'fixedWidth': true,
'fileName': 'app.[fontname].[chunkhash].[ext]'
};
================================================
FILE: test/package.json
================================================
{
"name": "webfonts-loader-test",
"private": true,
"main": "entry.js",
"scripts": {
"test": "rimraf ./dist && ava -v ./ava.js && webpack --mode production"
},
"devDependencies": {
"ava": "^5.1.0",
"css-loader": "^5.1.0",
"mini-css-extract-plugin": "^1.3.9",
"rimraf": "^3.0.2",
"style-loader": "^2.0.0",
"webpack": "^5.76.0",
"webpack-cli": "^4.5.0",
"webpack-dev-server": "^3.11.2"
},
"standard": {
"ignore": [
"./dist"
]
}
}
================================================
FILE: test/webpack.config.js
================================================
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: [
'./entry.js'
],
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
filename: 'app.bundle.js'
},
performance: {
hints: false
},
module: {
rules: [
{
test: /\.font\.js/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
url: false
}
},
require.resolve('../') // Replace this line with require('webfonts-loader')
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'app.bundle.[contenthash].css'
})
],
devServer: {
compress: true,
historyApiFallback: true,
host: 'localhost',
hot: true,
https: true,
inline: true,
port: '8080'
}
};
================================================
FILE: test-embed/ava.js
================================================
var test = require('ava');
var glob = require('glob').sync;
var hashFiles = require('../utils').hashFiles;
test('check consistency of files hash without hash length option', function (t) {
var files = glob('./test/test-svg/*.svg');
var expected = 'da39a3ee5e6b4b0d3255';
t.is(hashFiles(files), expected);
});
test('check consistency of files hash with min hash length option', function (t) {
var files = glob('./test/test-svg/*.svg');
var expected = 'da39a3ee';
var minHashLength = 8;
t.is(hashFiles(files, minHashLength), expected);
});
test('check consistency of files hash with max hash length option', function (t) {
var files = glob('./test/test-svg/*.svg');
var expected = 'da39a3ee5e6b4b0d3255bfef95601890';
var maxHashLength = 32;
t.is(hashFiles(files, maxHashLength), expected);
});
================================================
FILE: test-embed/entry.js
================================================
require('./myfont.font');
================================================
FILE: test-embed/myfont.font.json
================================================
{
"files": [
"./test-svg/*.svg"
],
"fontName": "myfonticons",
"classPrefix": "myfonticon-",
"baseSelector": ".myfonticon",
"types": ["eot", "woff2", "woff", "ttf", "svg"],
"fixedWidth": true,
"embed": true,
"fileName": "app.[fontname].[chunkhash].[ext]"
}
================================================
FILE: test-embed/package.json
================================================
{
"name": "webfonts-loader-test",
"private": true,
"main": "entry.js",
"scripts": {
"test": "rimraf ./dist && ava -v ./ava.js && webpack --mode production"
},
"devDependencies": {
"ava": "^5.1.0",
"css-loader": "^5.1.0",
"rimraf": "^3.0.2",
"style-loader": "^2.0.0",
"webpack": "^4.46.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.2"
},
"standard": {
"ignore": [
"./dist"
]
}
}
================================================
FILE: test-embed/webpack.config.js
================================================
const path = require('path');
module.exports = {
entry: [
'./entry.js'
],
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
filename: 'app.bundle.js'
},
performance: {
hints: false
},
module: {
rules: [
{
test: /\.font\.json/,
type: 'javascript/auto',
use: [
'style-loader',
'css-loader',
require.resolve('../') // Replace this line with require('webfonts-loader')
]
}
]
},
devServer: {
compress: true,
historyApiFallback: true,
host: 'localhost',
hot: true,
https: true,
inline: true,
port: '8080'
}
};
================================================
FILE: utils.js
================================================
var crypto = require('crypto');
var fs = require('fs');
module.exports = {
hashFiles: function (files, hashLength) {
// FIXME: For compatibility with the hash-files package, this
// function just sorts by filename and hashes the concatenation of
// the file contents. This algorithm will not detect certain
// changes where files are renamed or chunks are moved across
// file boundaries (https://github.com/mac-/hash-files/issues/4).
hashLength = hashLength && +hashLength >= 8 && +hashLength <= 32 ? +hashLength : 20;
var hash = crypto.createHash('sha1');
Array.from(new Set(files)).sort().forEach(function (file) {
hash.update(fs.readFileSync(file));
});
return hash.digest('hex').slice(0, hashLength);
}
};
gitextract_2b1_8_c3/ ├── .editorconfig ├── .github/ │ ├── FUNDING.yml │ └── workflows/ │ ├── codeql-analysis.yml │ ├── codeql.yml │ ├── dependency-review.yml │ ├── nodejs-test.yml │ ├── ossar.yml │ └── stale.yml ├── .gitignore ├── .npmignore ├── .snyk ├── LICENSE ├── README.md ├── emit-codepoints.js ├── index.js ├── package.json ├── runTest.sh ├── runTestEmbed.sh ├── test/ │ ├── ava.js │ ├── entry.js │ ├── myfont.font.js │ ├── package.json │ └── webpack.config.js ├── test-embed/ │ ├── ava.js │ ├── entry.js │ ├── myfont.font.json │ ├── package.json │ └── webpack.config.js └── utils.js
SYMBOL INDEX (4 symbols across 2 files)
FILE: emit-codepoints.js
method createArrayCodepointFiles (line 6) | createArrayCodepointFiles (codepointFiles, elem) {
method emitFiles (line 18) | emitFiles (loaderContext, emitCodepointsOptions, generatorOptions, optio...
FILE: index.js
function getFilesAndDeps (line 18) | function getFilesAndDeps (patterns, context) {
function wpGetOptions (line 63) | function wpGetOptions (context) {
Condensed preview — 29 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (39K chars).
[
{
"path": ".editorconfig",
"chars": 268,
"preview": "# http://editorconfig.org\n\nroot = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\nend_of_line = lf\ninsert"
},
{
"path": ".github/FUNDING.yml",
"chars": 15,
"preview": "github: jeerbl\n"
},
{
"path": ".github/workflows/codeql-analysis.yml",
"chars": 2728,
"preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
},
{
"path": ".github/workflows/codeql.yml",
"chars": 2729,
"preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
},
{
"path": ".github/workflows/dependency-review.yml",
"chars": 885,
"preview": "# Dependency Review Action\n#\n# This Action will scan dependency manifest files that change as part of a Pull Request, su"
},
{
"path": ".github/workflows/nodejs-test.yml",
"chars": 457,
"preview": "name: NodeJS\n\non:\n push:\n branches: [ \"master\" ]\n pull_request:\n branches: [ \"master\" ]\n\njobs:\n build:\n runs"
},
{
"path": ".github/workflows/ossar.yml",
"chars": 1937,
"preview": "# This workflow uses actions that are not certified by GitHub.\n# They are provided by a third-party and are governed by\n"
},
{
"path": ".github/workflows/stale.yml",
"chars": 421,
"preview": "name: Mark stale issues and pull requests\n\non:\n schedule:\n - cron: \"30 1 * * *\"\n\njobs:\n stale:\n\n runs-on: ubuntu-l"
},
{
"path": ".gitignore",
"chars": 66,
"preview": ".DS_Store\nnode_modules/\ntest/dist/\ntest-embed/dist/\nnpm-debug.log\n"
},
{
"path": ".npmignore",
"chars": 20,
"preview": "test/*\ntest-embed/*\n"
},
{
"path": ".snyk",
"chars": 307,
"preview": "# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.\nversion: v1.14.1\nignore: {}\n# patches ap"
},
{
"path": "LICENSE",
"chars": 1070,
"preview": "MIT License\n\nCopyright (c) 2017 Jerome Brunel\n\nPermission is hereby granted, free of charge, to any person obtaining a c"
},
{
"path": "README.md",
"chars": 7854,
"preview": "# webfonts-loader\n\n[](https://www.npmjs.com/package/webfonts-loa"
},
{
"path": "emit-codepoints.js",
"chars": 2271,
"preview": "var loaderUtils = require('loader-utils');\n\nvar hashFiles = require('./utils').hashFiles;\n\nmodule.exports = {\n createAr"
},
{
"path": "index.js",
"chars": 8463,
"preview": "var loaderUtils = require('loader-utils');\nvar webfontsGenerator = require('@vusion/webfonts-generator');\nvar path = req"
},
{
"path": "package.json",
"chars": 918,
"preview": "{\n \"name\": \"webfonts-loader\",\n \"version\": \"8.1.1\",\n \"description\": \"A WebPack loader to automatically generate font f"
},
{
"path": "runTest.sh",
"chars": 46,
"preview": "#!/bin/sh\n\ncd test && npm install && npm test\n"
},
{
"path": "runTestEmbed.sh",
"chars": 52,
"preview": "#!/bin/sh\n\ncd test-embed && npm install && npm test\n"
},
{
"path": "test/ava.js",
"chars": 820,
"preview": "var test = require('ava');\nvar glob = require('glob').sync;\nvar hashFiles = require('../utils').hashFiles;\n\ntest('check "
},
{
"path": "test/entry.js",
"chars": 26,
"preview": "require('./myfont.font');\n"
},
{
"path": "test/myfont.font.js",
"chars": 279,
"preview": "module.exports = {\n 'files': [\n './test-svg/*.svg'\n ],\n 'fontName': 'myfonticons',\n 'classPrefix': 'myfonticon-',"
},
{
"path": "test/package.json",
"chars": 495,
"preview": "{\n \"name\": \"webfonts-loader-test\",\n \"private\": true,\n \"main\": \"entry.js\",\n \"scripts\": {\n \"test\": \"rimraf ./dist &"
},
{
"path": "test/webpack.config.js",
"chars": 915,
"preview": "const path = require('path');\n\nconst MiniCssExtractPlugin = require('mini-css-extract-plugin');\n\nmodule.exports = {\n en"
},
{
"path": "test-embed/ava.js",
"chars": 820,
"preview": "var test = require('ava');\nvar glob = require('glob').sync;\nvar hashFiles = require('../utils').hashFiles;\n\ntest('check "
},
{
"path": "test-embed/entry.js",
"chars": 26,
"preview": "require('./myfont.font');\n"
},
{
"path": "test-embed/myfont.font.json",
"chars": 278,
"preview": "{\n \"files\": [\n \"./test-svg/*.svg\"\n ],\n \"fontName\": \"myfonticons\",\n \"classPrefix\": \"myfonticon-\",\n \"baseSelector\""
},
{
"path": "test-embed/package.json",
"chars": 455,
"preview": "{\n \"name\": \"webfonts-loader-test\",\n \"private\": true,\n \"main\": \"entry.js\",\n \"scripts\": {\n \"test\": \"rimraf ./dist &"
},
{
"path": "test-embed/webpack.config.js",
"chars": 671,
"preview": "const path = require('path');\n\nmodule.exports = {\n entry: [\n './entry.js'\n ],\n output: {\n path: path.resolve(__"
},
{
"path": "utils.js",
"chars": 763,
"preview": "var crypto = require('crypto');\nvar fs = require('fs');\n\nmodule.exports = {\n hashFiles: function (files, hashLength) {\n"
}
]
About this extraction
This page contains the full source code of the jeerbl/webfonts-loader GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 29 files (35.2 KB), approximately 9.7k tokens, and a symbol index with 4 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.