使用webpack处理自定义webfont(使用手写笔)

时间:2016-12-15 17:35:06

标签: html css webpack webfonts stylus

首先,请注意我是webpack的新手,这是我的第一个项目。

我试图将简单的webfont包含到我的webpack应用程序中,但很难在我的页面上看到它。

我的架构看起来像这样:

|-- app
|  |-- images
|  |  `-- icons
|  |-- index.html
|  |-- index.js
|  |-- scripts
|  `-- styles
|     |-- fonts
|     |  |-- HEINEKEN Core.eot
|     |  |-- HEINEKEN Core.otf
|     |  |-- HEINEKEN Core.svg
|     |  |-- HEINEKEN Core.ttf
|     |  |-- HEINEKEN Core.woff
|     |-- index.styl
|     |-- _fonts.styl
|-- package.json
|-- README.md
`-- webpack.config.js

我使用stylus-loaderstyle-loadercss-loader用于我的CSS:

{
  test: /\.styl$/,
  exclude: /node_modules/,
  loader: [
            'style-loader',
            'css-loader' + (!production ? '?sourceMap' : ''),
            'postcss-loader',
            'stylus-loader'
          ].join('!')
}

以及我试图包含" HEINEKEN"自定义字体(使用经典file-loader):

{
  test: /\.(eot|svg|ttf|woff|woff2)$/,
  exclude: /node_modules/,
  loader: 'file-loader?name=[path][name].[ext]&context=app/'
}

捆绑时,一切看起来都不错。字体文件被正确使用并且是最终包的一部分,但我的字体不适用于HTML,我不明白为什么。

webpack条目文件为index.js

import './index.html';
import './styles/index.styl';

这里是./styles/index.styl

@import '_fonts';

html
  font-family 'Heineken Core', serif

...和./styles/_fonts.styl

@font-face {
  font-family: 'Heineken Core';
  src: url('./fonts/HEINEKEN Core.eot');
  src: url('./fonts/HEINEKEN Core.eot?#iefix') format('embedded-opentype'),
       url('./fonts/HEINEKEN Core.woff') format('woff'),
       url('./fonts/HEINEKEN Core.ttf') format('truetype'),
       url('./fonts/HEINEKEN Core.svg#HEINEKENCore') format('svg');
  font-weight: normal;
  font-style: normal;
}

我已检查过字体路径,这是正确的。我想问题出在其他地方,但无法找到正在发生的事情。

任何帮助?

注意:我使用webpack-dev-server .. dunno,如果它可能导致问题。

提前,谢谢! :)

[编辑]这是我的完整配置:

const path              = require('path');
const webpack           = require('webpack');
const autoprefixer      = require('autoprefixer');

const production        = process.argv.indexOf("--production") > -1;

// Full Webpack Guide :
// https://medium.com/@dabit3/beginner-s-guide-to-webpack-b1f1a3638460#.olmn099wa
// and :
// https://julienrenaux.fr/2015/03/30/introduction-to-webpack-with-practical-examples/

var config = {
  entry: {
    vendor: ['jquery', 'jqvmap', 'gsap'],
    app: './app/index.js'
  },
  output: {
    path: path.join(__dirname, 'dist'),
    publicPath: !production ? 'http://localhost:8080/' : undefined,
    filename: 'bundle.js'
  },
  watch: !production,
  debug: !production,

  module: {
    preLoaders: [
      {
        test: /\.(js|es6)$/,
        exclude: /node_modules/,
        loader: 'jshint-loader'
      }
    ],
    loaders: [
      {
        test: /\.(js|es6)$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: { presets:[/*'react',*/'es2015'] } // Loader's options
      },
      {
        test: /\.styl$/,
        exclude: /node_modules/,
        loader: [
                  'style-loader',
                  'css-loader' + (!production ? '?sourceMap' : ''), // https://github.com/webpack/style-loader#recommended-configuration
                  'postcss-loader',
                  'stylus-loader'
                  // 'file-loader?name=[path][name].[ext]&context=app/'
                ].join('!')
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2)$/,
        exclude: /node_modules/,
        loader: 'file-loader?name=[path][name].[ext]&context=app/'
      },
      {
        test: /\.jpg$/,
        loader: 'file-loader?name=[path][name].[ext]&context=app/'
      },
      {
        test: /\.(png|gif)$/,
        loader: 'file-loader?name=[path][name].[ext]&context=app/' // 'url-loader?name=[path][name].[ext]&limit=150000' // filesize of < 150ko will be included as data URL
      },
      {
        test: /\.html$/,
        loader: [
                  'file-loader?name=[path][name].[ext]&context=app',
                  'extract-loader',
                  'html-loader'
                ].join('!')
      },

      // https://65535th.com/jquery-plugins-and-webpack/
      // https://github.com/webpack/expose-loader
      {
        test: require.resolve("jquery"),
        loader: [
                  'expose-loader?$',
                  'expose-loader?jQuery'
                ].join('!')
      }
    ]
  },

  resolve: {
    extensions: ['', '.js', '.es6'],

    //http://stackoverflow.com/a/28989476/1187888
    // alias: {
    //   jQuery: './node_modules/jquery/dist/jquery.js'
    // }
  },

  plugins: [
    // http://stackoverflow.com/a/28989476/1187888
    /*new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery"
    }),*/

    new webpack.optimize.CommonsChunkPlugin(/* chunkName= */"vendor", /* filename= */"vendor.bundle.js"/*, Infinity*/)
  ],

  // http://stackoverflow.com/a/33384364/1187888
  devServer: {
    contentBase: "./app",
    hot: true
  },

  // https://github.com/postcss/autoprefixer#webpack
  postcss: [ autoprefixer({ browsers: ['last 5 versions'] }) ],

  jshint: { 'esversion' : 6 }
};


// Empêche UglifyJS de gueuler sur le bundle de prod
// ---
if (production) {
  // http://stackoverflow.com/a/34071566/1187888
  config.plugins.push(
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      },
      exclude: /node_modules/
    })
  );
}


module.exports = config;

1 个答案:

答案 0 :(得分:3)

问题来自CSS处理相对路径的方式:

  

使用基本网址将相对网址解析为完整网址。 RFC 3986第3节定义了此过程的规范算法。对于CSS样式表,基本URL是样式表本身的URL,而不是样式化源文档的基本URL。

     

- CSS Values and Units Module Level 3

在我们的案例中,style-loader将样式添加到blob个对象,并通过<link>标记将其注入DOM:

 <link rel="stylesheet" href="blob:http://localhost:8080/4f0dcf58-1e22-46b5-bc74-60c97c1ad923">

CSS中的相对URL正在使用这些blob作为基础进行解析,而不是使用index.html加载的主机。而且预计在这些地方都找不到任何东西。

此问题的解决方案是在CSS引用中使用绝对URL,使用webpack配置中的output.publicPath选项可以轻松完成:

 module.exports = {
   output: {
     publicPath: (!production ? "http://localhost:8080/" : "http://your-production-host.com/")
   },
   // rest of your config options
 }