webpack TTF loader not loading the fonts - javascript

here is my code:
{
test: /\.ttf$/,
use: [
{
loader: 'ttf-loader',
options: {
name: './font/[hash].[ext]',
},
},
]
}
and tried with,
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader',
],
},
]
},
still gives this problem:
ERROR in ./src/client/assets/fonts/blacky.TTF 1:0
Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
# ./src/client/pages/Home/Homepage.module.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/client/pages/Home/Homepage.module.scss) 4:36-76
# ./node_modules/style-loader/dist/cjs.js!./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/client/pages/Home/Homepage.module.scss
I am aiming to convert my react app into an ssr app for firebase.
entire config file::
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins:
[
new MiniCssExtractPlugin({
filename:"[name].css",
chunkFilename:"[id].css"}),
],
entry: {
"app": "./src/client/index.js",
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
MiniCssExtractPlugin.loader,
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
exclude: /node_modules/,
},
{
test: /\.js$/,
loader: "babel-loader",
exclude: /node_modules/,
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
loader: 'url-loader',
options: {
limit: 10000
}
},
{
test: /\.ttf$/,
use: [
{
loader: 'ttf-loader',
options: {
name: './font/[hash].[ext]',
},
},
]
}
]
},
output: {
path: __dirname+"/functions/Views/public",
filename: "bundle.js",
},
}
(other problem that wasnt mentioned but still persits/ a lot more of the cmd error log)
r{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}#media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}#page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}
| /*# sourceMappingURL=bootstrap.min.css.map */
# ./src/client/pages/Header/navbar.js 15:0-46
# ./src/client/pages/Header/Header.js
# ./src/client/pages/about.js
# ./src/client/App.js
# ./src/client/index.js
Child mini-css-extract-plugin node_modules/style-loader/dist/cjs.js!node_modules/css-loader/dist/cjs.js!node_modules/sass-loader/dist/cjs.js!src/client/pages/Home/Homepage.module.scss:
Entrypoint mini-css-extract-plugin = *
[0] ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/client/pages/Home/Homepage.module.scss 1.04 KiB {0} [built]
[2] ./node_modules/style-loader/dist/cjs.js!./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/client/pages/Home/Homepage.module.scss 404 bytes {0} [built]
[5] ./src/client/assets/fonts/blacky.TTF 284 bytes {0} [built] [failed] [1 error]
+ 3 hidden modules
ERROR in ./src/client/assets/fonts/blacky.TTF 1:0
Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
# ./src/client/pages/Home/Homepage.module.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/client/pages/Home/Homepage.module.scss) 4:36-76
# ./node_modules/style-loader/dist/cjs.js!./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/client/pages/Home/Homepage.module.scss
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! AllianceCareLTD#0.2.0 webpack: `webpack-cli --config webpack.config.js`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the AllianceCareLTD#0.2.0 webpack script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\User\AppData\Roaming\npm-cache\_logs\2020-10-15T13_04_02_184Z-debug.log

A bit late but still worth to mention for anybody facing this issue. I was also spending some time with this topic and trying out many different things. And as I see all these inspired discussions in different forums, I can imagine that many new programmers are struggling with this topic. In the end I found a solution which worked for me. I hope it works for you, too.
FIRST
I use an outputPath for my fonts. It'll duplicate the font files, and place them into whatever directory in the "dist" folder depending on what we specify using outputPath - e.g. a path called "fonts". This is required for our fonts to be referenced correctly within your style file; for example scss or .js if you use styled-components and create a 'createGlobalStyle'. It also defines the relative paths for the output content which will be prefixed to every url request. In my case I use "fonts/". Example: If I implement font family yxz.woff, the path for the user in the frontend will be localhost:3000/fonts/yxz.woff in my case. It has nothing to do with my real folder structure in my project (see next paragraph).
// Webpack setting
{
test: /\.(woff|woff2|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "fonts/",
},
},
],
},
The font yxz.woff is placed directly in my public folder in the root directory. Any other placement can also be used (e.g. src/styles/fonts/yxz.woff) and works in my case. Figure it out for your project.
In the next step I define and load the yxz font with a .js file with styled-components. But scss works also in my case. Important here! You have to import every source (woff, woff2, ttf) separately and give it an unique name. See my following example
import { createGlobalStyle } from "styled-components";
import yxzWoff2 from "../../../public/yxz.woff2";
import yxzWoff from "../../../public/yxz.woff";
export default createGlobalStyle`
#font-face {
font-family: 'yxz';
src: local('yxzWoff2'),
url("fonts/yxz.woff2") format('woff2');
src: local('yxzWoff'),
url("fonts/yxz.woff") format('woff');
font-weight: normal;
font-style: normal;
font-display: auto;
}
`;
As you can see, I use the same paths as defined with webpack via outputPath. Still it is directly placed in the public folder. You can of course apply the above principle for ttf, too. However, in my case I mainly use woff and woff2.
I meanwhile have a quite large collection of fonts in the fonts folder structure in my project and it works. I hope this solves your issue and saves you and others here time.

Related

Build Error on importing images with react

I import images like this below:
import StepIcon from '../../public/images/icon_step.png'
and it works with no problem but when I run build I get the error below, guess I gotta fix webpack setting but I have no idea. how can i solve this problem?
Error
error in ./public/images/icon_step.png
Module build failed (from ./node_modules/file-loader/dist/cjs.js):
TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be one of type string, Buffer, TypedArray, or DataView. Received type function
at Hash.update (internal/crypto/hash.js:64:11)
at getHashDigest (/mnt/c/Users/wbvco/Desktop/Project Baby/styled-react-boilerplate/node_modules/loader-utils/lib/getHashDigest.js:48:8)
at url.replace (/mnt/c/Users/wbvco/Desktop/Project Baby/styled-react-boilerplate/node_modules/loader-utils/lib/interpolateName.js:96:11)
at String.replace (<anonymous>)
at Object.interpolateName (/mnt/c/Users/wbvco/Desktop/Project Baby/styled-react-boilerplate/node_modules/loader-utils/lib/interpolateName.js:93:8)
at Object.loader (/mnt/c/Users/wbvco/Desktop/Project Baby/styled-react-boilerplate/node_modules/file-loader/dist/index.js:27:36)
# ./src/components/signupstep.js 35:0-57 511:11-19
# ./src/pages/signup.js
# ./src/app.js
# ./src/index.js
# multi react-hot-loader/patch ./src/index.js
webpack Setting
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
},
}]
},
I think it's due to image relative path issue, can you try the below methods.
Simple method you should follow, see here for more info.
By using webpack
Please update the webpack like below
module: {
rules: [
{
test: /\.(jpe?g|gif|png|svg)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 10000
}
}
]
}
],
},
Then you can import the images from public folder to react component
import image from '../../public/assets/images/logo.png'
<img src={image}/>
By using require method
Also you can try this by install url-loader and file-loader
npm install url-loader file-loader --save-dev
Then update the webpack config as
module: {
loaders: [
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
]
}
and finally
<img src={require('./PATH_TO_IMAGE/IMAGE.png')}/>

How to transpile and minify single file with webpack?

I have a React application, and in my application I'm relying on react-scripts, so the build command is defined like this "build": "react-scripts build", and it works all fine. Now, the point is that inside my src directory I have a JS file called wrapper.js, which is a standalone file, and it is pure JS, no React stuff, but it uses ES6 and some newer features. So, what I want to do is that, I want create a new command, which will transpile and minify this file and will create a standalone copy of it. I thought to use webpack and I created a webpack.config.js file in the root of my project, which looks like this:
const path = require('path');
const MinifyPlugin = require('babel-minify-webpack-plugin');
module.exports = {
mode: 'production',
output: {
path: __dirname + 'build',
publicPath: '/build/',
filename: 'wrapper.js',
},
module: {
rules: [
{
test: /\.js$/,
include: [
path.resolve(__dirname, 'src', 'wrapper.js')
],
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
}
]
},
plugins: [
new MinifyPlugin()
]
};
And I added the following to my package.json file "wrapper": "webpack". Now, when I run npm run-scripts wrapper, it executes the webpack command, but it throws error. The output looks like this:
> webpack
Hash: 0aa67383ec371b8b7cd1
Version: webpack 4.19.1
Time: 362ms
Built at: 04/06/2019 10:54:46 AM
1 asset
Entrypoint main = wrapper.js
[0] ./src/index.js 223 bytes {0} [built] [failed] [1 error]
ERROR in ./src/index.js 22:4
Module parse failed: Unexpected token (22:4)
You may need an appropriate loader to handle this file type.
|
| ReactDOM.render(
> <Root />,
| document.getElementById('root'),
| );
What I see is that the problem is that webpack also tries to transpile and minify other files in my src directory, because it seems it has hit my React app's index.js file. How can I exclude everything? Or more precisely, how can I tell webpack to transpile and minify only the file /src/wrapper.js, and not to touch anything else at all?
Lighter weight alternative could be to create a script in your package.json and use babel-minify, https://babeljs.io/docs/en/babel-minify
package.json
{
...
"scripts": : {
"minify": "minify wrapper.js --out-file wrapper.min.js --mangle.keepClassName"
}
...
}
Add entry object to your webpack.config.js.
module.exports={
entry: './src/wrapper.js',
...
}
webpack points the entry object by default to ./src/index.js.
So if you don't override entry object, webpack will bundle the file in ./src/index.js
Update
To point to a output directory properly
output: {
filename: 'wrapper.js',
path: path.resolve(__dirname, 'build')
}

How to disable AMD on 4 files and load them in order with webpack

I need to disable AMD on 4 files and load video.js first before loading the other 3 files, because they depend on it. When I tried doing it in webpack.config.js like so:
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: './src/main.js',
output: {
path: __dirname + '/public',
filename: 'bundle.js'
},
devServer: {
inline: true,
contentBase: './src',
port: 3333
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
})
],
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules|lib/,
loader: 'babel',
query: {
presets: ['es2015', 'react', 'stage-2'],
plugins: ['transform-class-properties']
}
},
{
test: /\.json$/,
loader: 'json-loader'
},
{
test: /[\/\\]lib[\/\\](video|playlist|vpaid|overlay)\.js$/,
exclude: /node_modules|src/
loader: 'imports?define=>false'
}
]
}
}
It doesn't really work, because it just loads video.js (with disabled AMD) and completely ignores the other 3 files.
My folder structure is like so:
▾ lib/
overlay.js
playlist.js
video.js
vpaid.js
▸ node_modules/
▾ public/
200.html
bundle.js
▾ src/
App.js
index.html
main.js
LICENSE
package.json
README.md
webpack.config.js
Now, I found something that takes me 1 step back, because now even video.js doesn't load:
require('imports?define=>false!../lib/video.js')
require('imports?define=>false!../lib/playlist.js')
require('imports?define=>false!../lib/vpaid.js')
require('imports?define=>false!../lib/overlay.js')
and instead just throws these kinds of warnings:
WARNING in ./~/imports-loader?define=>false!./lib/video.js
Critical dependencies:
15:415-422 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
# ./~/imports-loader?define=>false!./lib/video.js 15:415-422
WARNING in ./~/imports-loader?define=>false!./lib/playlist.js
Critical dependencies:
10:417-424 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
# ./~/imports-loader?define=>false!./lib/playlist.js 10:417-424
WARNING in ./~/imports-loader?define=>false!./lib/vpaid.js
Critical dependencies:
4:113-120 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
# ./~/imports-loader?define=>false!./lib/vpaid.js 4:113-120
WARNING in ./~/imports-loader?define=>false!./lib/overlay.js
Critical dependencies:
10:416-423 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
# ./~/imports-loader?define=>false!./lib/overlay.js 10:416-423
So, my question is, how can I make this work in webpack.config.js so that I don't get these warnings?
I have solved the problem! To make this work you need this:
{
test: /[\/\\]lib[\/\\](video|playlist|vpaid|overlay)\.js$/,
exclude: /node_modules|src/
loader: 'imports?define=>false'
}
and this
require('script-loader!../lib/video.js')
require('script-loader!../lib/playlist.js')
require('script-loader!../lib/vpaid.js')
require('script-loader!../lib/overlay.js')
together!
Now, if you use this (instead of script-loader):
require('imports?define=>false!../lib/video.js')
require('imports?define=>false!../lib/playlist.js')
require('imports?define=>false!../lib/vpaid.js')
require('imports?define=>false!../lib/overlay.js')
It's not gonna work! (you need both imports-loader and script-loader working in unison.

Webpack production build does not load anything

I've been working on an app using React and Webpack for a little while. My development environment works fine, and everything loads properly using webpack-dev-server.
I decided to run a production build of the application to see what the end-product might look like size-wise and observe the general output of the webpack product build.
It turns out that running webpack -p, while it does produce output (more on that in a minute), does not load anything at all when I hit the site in a browser.. A quick check of the output tells me that none of my component code is making it into the webpack -p build.
The images and HTML copy over as they exist in my src (dev) folder, however my JS bundle output is extremely small - the file (main.js) is only 246 bytes.
Here is the output from running webpack -p
$ npm run build
> project#0.1.0 build /Users/me/Development/project
> NODE_ENV=production webpack -p --bail --progress --config webpack.config.babel.js
Hash: 9e5f6974ce21c920a375
Version: webpack 1.12.10
Time: 2003ms
Asset Size Chunks Chunk Names
index.html 1.45 kB [emitted]
images/edit.svg 524 bytes [emitted]
images/search.svg 1.19 kB [emitted]
main.js 246 bytes 0, 1 [emitted] javascript, html
+ 219 hidden modules
When I run the development version of the project, the output is markedly different... I know that the dev server dependencies are in there, and the code is not minified.. And, most importantly - everything works as expected when running the dev server.
$ npm start
> project#0.1.0 start /Users/me/Development/project
> webpack-dev-server --hot --display-modules --config webpack.config.babel.js
http://localhost:3333/
webpack result is served from /
content is served from /Users/me/Development/project/dist
Hash: 1b34ed58f9e323966ada
Version: webpack 1.12.10
Time: 2745ms
Asset Size Chunks Chunk Names
index.html 1.45 kB [emitted]
images/edit.svg 524 bytes [emitted]
images/search.svg 1.19 kB [emitted]
main.js 1.54 MB 0, 1 [emitted] html, javascript
Here's my webpack.config.babel.js file:
import webpack from 'webpack';
import path from 'path';
import ModernizrWebpackPlugin from 'modernizr-webpack-plugin';
import modernizrConfig from './modernizr.config';
const appDir = path.resolve(__dirname, './src');
const distDir = path.resolve(__dirname, './dist');
const nodeModulesDir = path.resolve(__dirname, './node_modules');
const excludeDirs = /(node_modules|bower_components)/;
module.exports = {
entry: {
javascript: appDir + '/main.js',
html: appDir + '/index.html'
},
output: {
path: distDir,
filename: 'main.js',
},
devServer: {
contentBase: distDir,
inline: true,
port: 3333
},
resolve: {
extensions: ['', '.js', '.es6'],
modulesDirectories: [
'node_modules',
'./src'
]
},
plugins: [
// new webpack.optimize.CommonsChunkPlugin('common.js'),
// new ModernizrWebpackPlugin(modernizrConfig),
],
sassLoader: {
sourceMap: false,
includePaths: [
appDir,
nodeModulesDir,
nodeModulesDir + '/breakpoint-sass/stylesheets/',
nodeModulesDir + '/susy/sass'
]
},
module: {
loaders: [
{ // js/jsx
test: /\.js?$/,
exclude: excludeDirs,
loader: 'babel',
query: {
cacheDirectory: true,
presets: [
'es2015', 'react'
]
}
},
{ // html
test: /\.html$/,
exclude: excludeDirs,
loader: 'file?name=[name].[ext]'
},
{ // images
test: /\.(gif|png|jpg|jpeg|svg)$/,
exclude: excludeDirs,
loader: 'file?name=images/[name].[ext]'
},
{ // sass
test: /\.scss$/,
exclude: excludeDirs,
loader: 'style!css!sass'
}
]
}
}
I don't think I've got a particularly complex, or uncommon setup, and I've tried changing everything from es2015/es6 to commonJS already as well, with the same result.
I'm at a loss as to what the issue could possibly be here; hoping that someone can point out some obvious error I've got, or perhaps suggest config updates/changes that could resolve this problem.
Thanks for taking the time to read everything!
As I mentioned in my comment, I've been using webpack successfully for months now, and I've never come across using an HTML file as an entry point.
Usually you'll use Webpack to package up javascript, css, and sometimes images (ie: "assets") to be used by an html file. Serving that HTML file is outside the realm of Webpack's responsibility.
I would suggest using Webpack to generate only the final javascript bundle, then using some other method (ie: express, or some other web server) to serve that file and the html that consumes it.

Webpack - sass loader cannot find images

The sass loader doc says: "If you're just generating CSS without passing it to the css-loader, it must be relative to your web root".
So i did as it tells, I have my index.html in my project root, then I'm trying to load an image from my scss file.
Now I have 2 errors: 1) from Chrome's console: Cannot find module "./img/header.jpg". 2) from my terminal:
ERROR in ./~/css-loader!./~/sass-loader!./~/resolve-url-loader!./public/css/header.scss
Module not found: Error: Cannot resolve 'file' or 'directory' ./img/header.jpg in C:\Web-Development\React\Portfolio\public\css
# ./~/css-loader!./~/sass-loader!./~/resolve-url-loader!./public/css/header.scss 6:64-91
webpack.config.js
module.exports = {
entry: './main.jsx',
output: {
filename: './public/js/build/bundle.js'
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel',
query: {
presets: ['react', 'es2015']
}
},
{
test: /\.scss$/,
loaders: ["style", "css", "sass", "resolve-url"]
},
{
test: /\.jpg$/,
loader: "file?name=[path][name].[ext]"
}
]
}
};
If I see my code, I can clearly see that my css lives inside <head> so I've pointed my image's path to my root, as documentation says, but still can't fix it.
UPDATE:
I've installed file-loader and followed the instructions, now I get this error in console: GET http://localhost:3000/public/img/header.jpg 404 (Not Found) - jquery.js:9119
As far as I can see you are actually using the css loader ( "style", "css", "sass", "resolve-url" ) (the "css" part is the "css-loader")
In your sass file(s) you should link to the images using a relative path from the sass file you are editing.
styles
- somefile.scss
- another.scss
images
- someImage.jpg
in somefile.scss, you should link to your image like this:
background-image: url("../images/someImage.jpg);
Do note, that if you want webpack to move those images to your distribution folder (if you are using a system like this) that you will need something like file-loader to copy those files over.
You can use ignore-loader if your images are already in the place where you need them. file-loader will copy the files to your output folder.
To solve this problem I've uploaded this webpack extremly basic configuration to start my projects, I hope it can help everyone who had this problem. Suggestions are all welcome of course.

Categories