2016-12-26 78 views
4

我想在我的React项目中使用一些本地网络字体。我将它们包含在我的main.scss文件中,并通过webpack加载它们。该包正确构建,包括main.scss样式。我看到webpack加载字体文件,并将它们复制到public/fonts /,但是我的软件包文件找不到字体。使用webpack的本地网络字体

据我所知,你的@ font-face src应该与bundle的位置有关。我将它设置为与我在webpack中加载字体相同的路径,'./fonts/'。我看到确切的错误是:

file:///Users/myusername/Documents/folder1/folder2/folder3/APP/fonts/FoundersGroteskWeb-Regular.woff net::ERR_FILE_NOT_FOUND 

我一直在尝试不同的路径配置,并且使用的WebPack的publicPath选项,但我在这一点上兜兜了什么似乎像一个非常简单的参考错误。

文件结构:

APP 
├──webpack.config.js 
├──src 
    ├──app 
     ├──App.jsx 
     ├──styles 
      ├──main.scss 
      ├──fonts 
       ├──allthefonts.woff 
    ├──public 
     ├──bundle.js 
     ├──fonts 
      ├──allthefonts.woff 

App.jsx:

require('./styles/main.scss'); 

main.scss:

@font-face { 
    font-family: FoundersGrotesk; 
    src: url('./fonts/FoundersGroteskWeb-Bold.eot') format('eot'), 
     url('./fonts/FoundersGroteskWeb-Bold.woff') format('woff'), 
     url('./fonts/FoundersGroteskWeb-Bold.woff2') format('woff2'); 
    font-weight: bold; 
} 

@font-face { 
    font-family: FoundersGrotesk_Cnd; 
    src: url('./fonts/FoundersGrotXCondWeb-Bold.eot') format('eot'), 
     url('./fonts/FoundersGrotXCondWeb-Bold.woff') format('woff'), 
     url('./fonts/FoundersGrotXCondWeb-Bold.woff2') format('woff2'); 
    font-weight: bold; 
} 

@font-face { 
    font-family: FoundersGrotesk; 
    src: url('./fonts/FoundersGroteskWeb-Regular.eot') format('eot'), 
     url('./fonts/FoundersGroteskWeb-Regular.woff') format('woff'), 
     url('./fonts/FoundersGroteskWeb-Regular.woff2') format('woff2'); 
    font-weight: normal; 
} 

个webpack.config.js:

'use strict'; 

const webpack = require('webpack'); 
const PROD = JSON.parse(process.env.PROD_ENV || '0'); 

module.exports = { 

    entry: './src/app/App.jsx', 

    output: { 
    path: './src/public/', 
    filename: PROD ? 'bundle.min.js' : 'bundle.js' 
    }, 

    module: { 
    loaders: [ 
     { 
     test: /\.jsx?$/, 
     loader: 'babel-loader', 
     exclude: '/node_modules/', 
     query: { 
      presets: ['es2015', 'react', 'stage-1'] 
     } 
     }, 
     { 
     test: /\.s?css$/, 
     loaders: ['style', 'css', 'sass'] 
     }, 
     { 
     test: /\.(eot|svg|ttf|woff|woff2)$/, 
     loader: 'file-loader?name=./fonts/[name].[ext]' 
     } 
    ] 
    } 
}; 
+2

不要用'eot'字体麻烦 - 他们只为IE8及以下,微软在2016年IE9的月及以上的所有支持WOFF抛弃。在另一个注意事项上:不要将你的静态资产放入你的包中,将它们作为静态内容提供。它为您和您的用户节省了大量的带宽,因为静态资产一直以来一直存在,并且一直保持到浏览器缓存的状态。如果将它们捆绑在一起,就会迫使海量数据没有通过网络改变,导致用户花费金钱,耗费用户时间,并导致不必要的糟糕体验。 –

+0

@ Mike'Pomax'Kamermans我可能会误解,但不是文件加载器只是将资源从dev目录复制到build目录,这样bundle可以轻松引用它们?这是我在文章/ SO帖子中看到的处理图像或字体的方法,我不知道你会如何使用它们。 – johnjohn

+0

如果我们谈论的是https://github.com/webpack/file-loader,那么:有点儿,但它也做了各种各样的时髦的重命名。如果您只需要资产重新定位,那么使用“cp assets build”代替它更有意义。无论如何,你的JS代码不需要“需要”静态资产 –

回答

4

this thread得到了有效的解决方案感谢@omerts。涉及使用publicPath的解决方案。我一直试图将它作为module.exports中带有字体文件加载器的选项来使用,而不是输出。

更新webpack.config.js

const webpack = require('webpack'); 
const PROD = JSON.parse(process.env.PROD_ENV || '0'); 
const path = require('path'); 

const PATHS = { 
    build: path.join(__dirname, './src/public') 
}; 

module.exports = { 

    entry: './src/app/App.jsx', 

    output: { 
    path: PATHS.build, 
    filename: PROD ? 'bundle.min.js' : 'bundle.js', 
    publicPath: PATHS.build 
    }, 

    module: { 
    loaders: [ 
     { 
     test: /\.jsx?$/, 
     loader: 'babel-loader', 
     exclude: '/node_modules/', 
     query: { 
      presets: ['es2015', 'react', 'stage-1'] 
     } 
     }, 
     { 
     test: /\.s?css$/, 
     loaders: ['style', 'css', 'sass'] 
     }, 
     { 
     test: /\.(eot|svg|ttf|woff|woff2)$/, 
     loader: 'file-loader?name=/fonts/[name].[ext]' 
     }, 
     { 
     test: /\.(jpg|png)$/, 
     loader: 'file-loader?name=/fonts/[name].[ext]' 
     } 
    ] 
    }, 

    plugins: PROD ? [ 
    new webpack.optimize.UglifyJsPlugin({ 
     beautify: false, 
     comments: false, 
     compress: { 
     warnings: false, 
     drop_console: true 
     }, 
     mangle: { 
     except: ['$'], 
     screw_ie8: true, 
     keep_fnames: false 
     } 
    }) 
    ] : [] 
}; 
0

一个更好的办法是使用“网址加载器”,并添加下面的行装载机。

{ 
    test: /\.(jpe?g|png|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/, 
    loader: 'url-loader?limit=100000' 
}