使用 webpack 在 react-rails 应用程序中从 node_modules 加载字体
Load fonts from node_modules in react-rails application with webpack
我有一个使用 webpacker 设置的 react-rails 应用程序。
我正在尝试使用 node_modules 中的字体加载 font-awesome-pro。
我认为这是一项微不足道的任务,但我似乎找不到任何关于如何执行此操作的好文档。
这是我目前拥有的:
package.json 依赖关系:
"dependencies": {
"@rails/webpacker": "3.5",
"babel-preset-react": "^6.24.1",
"bootstrap": "^4.1.3",
"prop-types": "^15.6.2",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-slick": "^0.23.1",
"react_ujs": "^2.4.4",
"slick-carousel": "^1.8.1",
"tachyons-z-index": "^1.0.9"
},
"devDependencies": {
"@fortawesome/fontawesome-pro": "^5.2.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-preset-env": "^1.7.0",
"file-loader": "^2.0.0",
"path": "^0.12.7",
"webpack-dev-server": "2.11.2"
}
file.js:
var path = require('path');
module.exports = {
test: /\.(woff(2)?|eot|otf|ttf|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
exclude: path.resolve(__dirname, '../../app/assets'),
use: {
loader: 'file-loader',
options: {
outputPath: 'fonts/',
useRelativePath: false
}
}
}
environment.js
const { environment } = require('@rails/webpacker')
const file = require('./file')
environment.loaders.prepend('file', file)
module.exports = environment
application.scss:
@import '@fortawesome/fontawesome-pro/scss/fontawesome.scss';
application.rb:
config.assets.paths << Rails.root.join('node_modules')
我错过了什么?据我所知,webpack 应该查看 node_modules
目录,根据 webpack test
查找字体文件并将资产放入输出目录:fonts/
.
带有网络字体的 FontAwesome:
对于我来说,使用免费版本,下面的示例运行良好。我不知道专业版,但如果我没记错的话,你只需要在路径中将 fontawesome-free
重命名为 fontawesome-pro
。
application.scss:
$fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
@import "~@fortawesome/fontawesome-free/scss/fontawesome.scss";
@import "~@fortawesome/fontawesome-free/scss/solid.scss";
@import "~@fortawesome/fontawesome-free/scss/regular.scss";
@import "~@fortawesome/fontawesome-free/scss/brands.scss";
在 SCSS 中 ~
(波浪号导入)表示查找最近的 node_modules
目录。并非所有 SASS 编译器都支持它,但 node-sass
支持,这是 Webpack 的共同点。
这样在您的 html
中您只需要使用您的 application.css
。无需包含任何其他 FontAwesome css 文件。
您的字体加载器配置似乎没问题(已测试,有效)。使用该 Webpack 应该解析字体文件,然后根据需要将它们复制到所需的输出。这需要您的 css-loader
配置为 url: true
但我这是默认值。
Webpack 配置文件中加载程序的 minimal/usual 配置:
module: {
rules: [
{
test: /\.s?css$/,
use: [
MiniCssExtractPlugin.loader, // optional (the most common way to export css)
"css-loader", // its url option must be true, but that is the default
"sass-loader"
]
},
{
// find these extensions in our css, copy the files to the outputPath,
// and rewrite the url() in our css to point them to the new (copied) location
test: /\.(woff(2)?|eot|otf|ttf|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: {
loader: 'file-loader',
options: {
outputPath: 'fonts/'
}
}
}
]
},
只加载需要的字体(使用 JS 和 SVG 的新方法)
再说一次,我用免费版演示,因为我没有专业版。
这样,您生成的捆绑包将只包含您需要的那些图标,从而产生更小的尺寸,这意味着更快的页面加载。 (我在我的项目中使用它)
需要的包:
@fortawesome/fontawesome-svg-core
@fortawesome/free-brands-svg-icons
@fortawesome/free-regular-svg-icons
@fortawesome/free-solid-svg-icons
将此包含在您的 css 文件中:
@import "~@fortawesome/fontawesome-svg-core/styles";
新建一个文件,命名为fontawesome.js:
import { library, dom, config } from '@fortawesome/fontawesome-svg-core';
config.autoAddCss = false;
config.keepOriginalSource = false;
config.autoReplaceSvg = true;
config.observeMutations = true;
// this is the 100% working way (deep imports)
import { faUser } from '@fortawesome/free-solid-svg-icons/faUser';
import { faHome } from '@fortawesome/free-solid-svg-icons/faHome';
import { faFacebook } from '@fortawesome/free-brands-svg-icons/faFacebook';
import { faYoutube } from '@fortawesome/free-brands-svg-icons/faYoutube';
// this is the treeshaking way (better, but read about it below)
import { faUser, faHome } from '@fortawesome/free-solid-svg-icons';
import { faFacebook, faYoutube } from '@fortawesome/free-brands-svg-icons';
library.add(faUser, faHome, faFacebook, faYoutube);
dom.watch();
.. 然后在你的 js 中的某处要求它:
require('./fontawesome');
就是这样。如果你想阅读更多这方面的内容,请从理解 SVG JavaScript Core, have a look on its configuration and read the documantation of treeshaking 开始。
我有一个使用 webpacker 设置的 react-rails 应用程序。
我正在尝试使用 node_modules 中的字体加载 font-awesome-pro。
我认为这是一项微不足道的任务,但我似乎找不到任何关于如何执行此操作的好文档。
这是我目前拥有的:
package.json 依赖关系:
"dependencies": {
"@rails/webpacker": "3.5",
"babel-preset-react": "^6.24.1",
"bootstrap": "^4.1.3",
"prop-types": "^15.6.2",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-slick": "^0.23.1",
"react_ujs": "^2.4.4",
"slick-carousel": "^1.8.1",
"tachyons-z-index": "^1.0.9"
},
"devDependencies": {
"@fortawesome/fontawesome-pro": "^5.2.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-preset-env": "^1.7.0",
"file-loader": "^2.0.0",
"path": "^0.12.7",
"webpack-dev-server": "2.11.2"
}
file.js:
var path = require('path');
module.exports = {
test: /\.(woff(2)?|eot|otf|ttf|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
exclude: path.resolve(__dirname, '../../app/assets'),
use: {
loader: 'file-loader',
options: {
outputPath: 'fonts/',
useRelativePath: false
}
}
}
environment.js
const { environment } = require('@rails/webpacker')
const file = require('./file')
environment.loaders.prepend('file', file)
module.exports = environment
application.scss:
@import '@fortawesome/fontawesome-pro/scss/fontawesome.scss';
application.rb:
config.assets.paths << Rails.root.join('node_modules')
我错过了什么?据我所知,webpack 应该查看 node_modules
目录,根据 webpack test
查找字体文件并将资产放入输出目录:fonts/
.
带有网络字体的 FontAwesome:
对于我来说,使用免费版本,下面的示例运行良好。我不知道专业版,但如果我没记错的话,你只需要在路径中将 fontawesome-free
重命名为 fontawesome-pro
。
application.scss:
$fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
@import "~@fortawesome/fontawesome-free/scss/fontawesome.scss";
@import "~@fortawesome/fontawesome-free/scss/solid.scss";
@import "~@fortawesome/fontawesome-free/scss/regular.scss";
@import "~@fortawesome/fontawesome-free/scss/brands.scss";
在 SCSS 中 ~
(波浪号导入)表示查找最近的 node_modules
目录。并非所有 SASS 编译器都支持它,但 node-sass
支持,这是 Webpack 的共同点。
这样在您的 html
中您只需要使用您的 application.css
。无需包含任何其他 FontAwesome css 文件。
您的字体加载器配置似乎没问题(已测试,有效)。使用该 Webpack 应该解析字体文件,然后根据需要将它们复制到所需的输出。这需要您的 css-loader
配置为 url: true
但我这是默认值。
Webpack 配置文件中加载程序的 minimal/usual 配置:
module: {
rules: [
{
test: /\.s?css$/,
use: [
MiniCssExtractPlugin.loader, // optional (the most common way to export css)
"css-loader", // its url option must be true, but that is the default
"sass-loader"
]
},
{
// find these extensions in our css, copy the files to the outputPath,
// and rewrite the url() in our css to point them to the new (copied) location
test: /\.(woff(2)?|eot|otf|ttf|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: {
loader: 'file-loader',
options: {
outputPath: 'fonts/'
}
}
}
]
},
只加载需要的字体(使用 JS 和 SVG 的新方法)
再说一次,我用免费版演示,因为我没有专业版。
这样,您生成的捆绑包将只包含您需要的那些图标,从而产生更小的尺寸,这意味着更快的页面加载。 (我在我的项目中使用它)
需要的包:
@fortawesome/fontawesome-svg-core
@fortawesome/free-brands-svg-icons
@fortawesome/free-regular-svg-icons
@fortawesome/free-solid-svg-icons
将此包含在您的 css 文件中:
@import "~@fortawesome/fontawesome-svg-core/styles";
新建一个文件,命名为fontawesome.js:
import { library, dom, config } from '@fortawesome/fontawesome-svg-core';
config.autoAddCss = false;
config.keepOriginalSource = false;
config.autoReplaceSvg = true;
config.observeMutations = true;
// this is the 100% working way (deep imports)
import { faUser } from '@fortawesome/free-solid-svg-icons/faUser';
import { faHome } from '@fortawesome/free-solid-svg-icons/faHome';
import { faFacebook } from '@fortawesome/free-brands-svg-icons/faFacebook';
import { faYoutube } from '@fortawesome/free-brands-svg-icons/faYoutube';
// this is the treeshaking way (better, but read about it below)
import { faUser, faHome } from '@fortawesome/free-solid-svg-icons';
import { faFacebook, faYoutube } from '@fortawesome/free-brands-svg-icons';
library.add(faUser, faHome, faFacebook, faYoutube);
dom.watch();
.. 然后在你的 js 中的某处要求它:
require('./fontawesome');
就是这样。如果你想阅读更多这方面的内容,请从理解 SVG JavaScript Core, have a look on its configuration and read the documantation of treeshaking 开始。