jeerbl/webfonts-loader

How to use this with SASS?

Closed this issue ยท 10 comments

Thanks for this great module and for releasing it for WebPack2 ๐Ÿ‘

I'm having some troubles using it in production, because we have a special webpack entry for (styles.scss) that compiles everything into one .css file. Imports are done via @import 'another (s)css file';

We woule like to let the css file should hold all our styles, therefore I would like to include the font in that too. But of course require ('../icons/app.font') is not working inside an (s)css file that gets loaded via the sass-loader first. Is it possible to circumvent this?

Well I would set the Webpack entry file as entry.js. Inside entry.js I would require both the SASS file that was set your Webpack entry file before and the font config file.

Would that work in your case?

I'd love to do it that way, but webpack does not work with extracttext in combination with commonschunks for sass files that are included via the @import statement.

So I now created a seperate entry: iconfont : ['./path/to/iconfont.font'].

Then in my iconfont.font:

module.exports = {
/* For webfont /
"files": [
"../icons/
.svg" // glob style from the current directory
],
"fontName": "icons",
"classPrefix": "ico-",
"baseSelector": ".ico",
"fixedWidth": true,
"types": ["woff2", "eot", "woff", "ttf"], // this is the default
'fileName': 'app-[fontname].[hash].[ext]'
/* end webfont */
};

I do see that the fonts are created now. (app-icons-hash.woff2, etc). But there is no css file generated.

Do I need to import/require something?

Thanks for your time :)

Could you please send me the part of your webpack config that loads the font config file?

module.exports =  {
          name: 'index',
	  context: __dirname,

	  entry: {
	        // Some javascript you want in the header (for now only jQuery..)
	  	iconfont: ['./assets/entries/iconfont.font'],
	        header: ["./assets/entries/header.js",],
	        tinymce: ["./assets/entries/tinymce.js",],
	        styles: ['./assets/entries/styles.scss'],  // this file includes all styles, because webpack does not work with extracttext in combination with commonschunks for sass files that are includes via the @import statement.
	  	datetimepicker: ['./assets/entries/datetimepicker.js'],
	  	landing: ['./assets/entries/landing.js'],
	  	manual_bootstrap_modal_loaded_event: ['./assets/entries/manual_bootstrap_modal_loaded_event'],
	  	// Extensions:
	  	fileupload: ['./assets/entries/fileupload.js'],
	  	desktop: ['./assets/entries/desktop.js'],
	  	mobile: ['./assets/entries/mobile.js'],
	  	print: ['./assets/entries/print.scss']  // All styles for printing
	    },
		 
	      
	  output: {
	      path: path.resolve('./assets/bundles/'),
	      filename: "[name]-[hash].js",
	      chunkFilename: "[name]-[id]-[chunkhash].js"
	  },

	  plugins: [
	        // add header (mainly jQuery)
	        new webpack.optimize.CommonsChunkPlugin({
	            name: "header",
	            minChunks: Infinity,
	        }),
	        // add common as a parent of everything (is used in everything)
	        new webpack.optimize.CommonsChunkPlugin({
	            name: "common",
	            chunks: ["landing"],
	            //minChunks: Infinity,
	        }),

		//new webpack.optimize.CommonsChunkPlugin({
		//  names: ['common', 'manifest'], // add manifest chunk
		//  minChunks: Infinity
		//}),
	        new ExtractTextPlugin({
	        	filename:'[name]-[chunkhash].css', 
	        }),
	        new webpack.ProvidePlugin({
	            // Here are all the global variables stated
		    $: "jquery",
		    jQuery: "jquery",
		    Mustache: "mustache",
		    c3: "c3"
 
		}),
    	    new WebpackChunkHash(),
	    new ChunkManifestPlugin({
	      filename: "chunk-manifest.json",
	      manifestVariable: "webpackManifest"
	    })
	  ], 

	  module: {
	    rules: [  
	        /// should always be first (for production not to break)  
		{ 
		test: /\.scss$/,
		exclude: ['node_modules', 'bower_components'],
		loader: ExtractTextPlugin.extract({ 
		        fallback: 'style-loader', 
			use: [
			      'css-loader?importLoaders=1',
          		      'postcss-loader',
			      'sass-loader'
			     ]
		     })
	      },
	      /// should always be second (for production not to break)  
		{
		test: /\.css$/,
		exclude: ['node_modules', 'bower_components'],
		loader: ExtractTextPlugin.extract({ 
		        fallback: 'style-loader', 
			use: [
			      'css-loader?importLoaders=1',
          		      'postcss-loader'
          		     ]
		     })
	      },
	    
	      
	      /*{  enables linting, would be cool if there weren't so many warnings
	         enforce: 'pre',
           	 test: /\.js$/,
                 loader: 'eslint-loader',		            
                 exclude: [ /node_modules/ ]
              },*/
              
                    {
			test: /\.font$/,
			loader: "style-loader!css-loader!webfonts-loader"
		    },
		    {
		      test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
		      loader: "url-loader?limit=100&mimetype=application/font-woff"
		    }, {
		      test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
		      loader: "url-loader?limit=100&mimetype=application/font-woff"
		    }, {
		      test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
		      loader: "url-loader?limit=100&mimetype=application/octet-stream"
		    }, {
		      test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
		      loader: "file-loader"
		    }, {
		      test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
		      loader: "url-loader?limit=100&mimetype=image/svg+xml"
		    },
	      { test: /\.(png|jpg|gif)$/, loader: 'url-loader?limit=1000' },
          
	      { test: /jquery[\\\/]src[\\\/]selector\.js$/, loader: 'amd-define-factory-patcher-loader' },
	      {test: require.resolve('offline-js/js/offline'), loader: 'exports-loader?window.Offline'},
	      {
            	test: require.resolve('jquery-form'),
            	loader: "imports-loader?define=>false"
        	},
             /*{ test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/,
              loader: "imports-loader?this=>window" }*/
	    ] // add all common loaders here
	  },
	  resolve: {
	    modules: [path.resolve(__dirname, "assets", "js", "apps"), 'node_modules', 'bower_components'],
	    extensions: ['.js','.jsx', '.scss'], //, '.css'],
            descriptionFiles: ["package.json", "bower.json"], // These JSON files are read in directories
	    alias: {
	      'jquery-ui/widget': 'blueimp-file-upload/js/vendor/jquery.ui.widget.js',
              "jquery": "jquery/src/jquery",
	    }
	  }
};

Sorry for the mess.

I'm just thinking: should I import / require the font somewhere, or is the inclusion via the entry enough?(sorry for my questions, I'm working with webpack for less then a month, so I'm learning a lot of new things)

I see your CSS and SCSS files are going through the ExtractTextPlugin, try to do that with the font file as well.

(closed by mistake)

Whoosh!! I wrote the webpack.config myself, but I needed to do so in a rush, which means I forgot the ExtractPlugin afterwards, but it is working now!! Thanks!

Changes:

                    {
			test: /\.font$/,
			exclude: ['node_modules', 'bower_components'],
			loader: ExtractTextPlugin.extract({ 
				fallback: 'style-loader', 
				use: [
				      'css-loader?importLoaders=1',
		  		      'webfonts-loader'
		  		     ]
			     })
		    },

No problem

Cheers
Jerome

Just one thing though, the url in the iconfont looks like the following:

(this make it doesn't find the fonts). Would it be possible to use a relative url that goes through the url-loader?

@font-face {
	font-family: "iconfont";
	src: url("/app-iconfont.3b1036efa0aa07fe1008c4c3ef458154.woff2") format("woff2"),
url("/app-iconfont.5b2854bc16fd0985efd431b2e938f6e6.eot?#iefix") format("embedded-opentype"),
url("/app-iconfont.9e46112d79582056ea36b0f413f24a72.woff") format("woff"),
url("/app-iconfont.3f67f866869b75b950e6c70070b5ac47.ttf") format("truetype");
}

.ico{
	line-height: 1;
}

.ico:before {
	font-family: iconfont!important;
	font-style: normal;
	font-weight: normal !important;
	vertical-align: top;
}
.ico-split_arrow:before {
	content: "\F104";
}
.ico-syringe:before {
	content: "\F105";
}

I solved it now by embedding the font, which is extra awesome :)