使用webpack从react-rails应用程序中的node_modules加载字体

我有一个使用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 with webfonts:

对于我的免费版本,下面的示例运行良好。 我不知道专业版,但是如果我没有弄错的话,你只需要在路径fontawesome-pro 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的常见function。

这种方式在你的html你只需要使用你的application.css 。 没有必要包含任何其他FontAwesome css文件。

你的字体加载器配置似乎没问题(测试,工作)。 使用该Webpack应解析字体文件,然后根据需要将它们复制到所需的输出。 这需要你的css-loader配置url: true但我是默认的。

Webpack配置文件中加载器的最小/常规配置:

 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 

将其包含在您的scss文件中:

 @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 ,查看其配置并阅读treeshaking的文档 。