【问题标题】:Load fonts from node_modules in react-rails application with webpack使用 webpack 从 react-rails 应用程序中的 node_modules 加载字体
【发布时间】:2018-10-09 04:28:48
【问题描述】:

我有一个使用 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"
  }

文件.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
      }
    }
}

环境.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';

应用程序.rb:

config.assets.paths << Rails.root.join('node_modules')

我错过了什么?据我所知,webpack 应该查看 node_modules 目录,根据 webpack test 查找字体文件并将资产放入输出目录:fonts/

【问题讨论】:

    标签: ruby-on-rails ruby webpack webpacker react-rails


    【解决方案1】:

    FontAwesome with webfonts:

    对于使用免费版本的我来说,下面的示例运行良好。我不知道专业版,但如果我没记错的话,你只需要将路径中的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 配置文件中加载程序的最小/常规配置:

    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 开始,查看其configuration 并阅读treeshaking 的文档。

    【讨论】:

    • 如果Libsass在编译过程中抛出一个弃用警告,here is the whyhere is my feature request给FontAwesome可以轻松避免。
    • 这是我需要的,但是有很多额外的信息令人困惑。对于遇到此问题的其他人,您可能只需要对application.scss(或等效项)进行提到的更改即可。
    猜你喜欢
    • 2017-02-19
    • 2020-01-26
    • 2022-12-15
    • 1970-01-01
    • 2017-10-18
    • 2021-12-03
    • 1970-01-01
    • 2023-02-17
    • 2021-07-02
    相关资源
    最近更新 更多