Webpack pdf file loader - reactjs

This is the error:
"Build failed!
× ERROR ./media/fonts/handFont3.otf 1:4.
Module parse failed: Unexpected token (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)
# ./index.js 3:0-37
# ../node_modules/preact-cli/lib/lib/entry.js
# multi ../node_modules/preact-cli/lib/lib/entry webpack-dev-server/client webpack/hot/dev-server"
I'm trying to import pdf into preact component to make it build so I can get the link to the page with pdf file. Here is how:
import pdfFile from '../../media/images/pdfFile.pdf'
<a href={pdfFile} target="_blank"...
It didn't work, so I Googled this two solutions to add in wepback.config.js:
module.exports = {
module: {
rules: [
{
test: /\.(png|svg|jpg|gif|pdf)$/,
use: ['file-loader']
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: ['file-loader']
},
]
},
};
and
{
test: /\.(pdf)$/,
use: ['url-loader']
},
I do manually make webpack.config work by this string:
--config webpack.config.js
And file is working, but result is the same. I'm still getting the error. And the same with otf fonts.
Thank you.

I figured out the solution. You can't use webpack config with preact config together.
So I removed webpack config and changed preact one to this:
export default (config, env, helpers, options) => {
const rule = {
test: /\.(otf|pdf)$/,
loader: 'file-loader'
}
config.module.rules.push(rule);
}

Related

How can I fix the "Failed to parse source map from ..." errors in my ReactJS/TS project

I have a ReactJS project where I wanted to use a Barcode-Scanner npm module with the name html5-qrcode, but I always get this error:
Failed to parse source map from 'C:\...\node_modules\html5-qrcode\third_party\index.js.map' file: Error: ENOENT: no such file or directory, open 'C:\...\node_modules\html5-qrcode\third_party\index.js.map'
And then there are errors like: (seperated for readability)
WARNING in ./node_modules/html5-qrcode/esm/camera/core-impl.js Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from 'C:\...\node_modules\src\camera\core-impl.ts' file: Error: ENOENT: no such file or directory, open 'C:\...\node_modules\src\camera\core-impl.ts'
I thought it might be an TS error, because every file of the second error part has a .ts ending.
So I made a new ReactTS project with all components and co in it, but I still get the same error.
I thought it might be an TS error, because every file of the second error part has a .ts ending. So I made a new ReactTS project with all components and co in it, but I still get the same error.
It seems like the npm package has issues with its source maps and webpacks's source-map-loader module is not able to process them. This doesn't really affect the application itself but having all those warnings is annoying.
I came across two solutions: either force the source-map-loader to skip the culprit package or ignore source-map warnings all together.
To achieve either solution, you'll need to be able to override the webpack.config.js. How to override it really depends on the framework you use to run your React apps (I have mine setup using NX)
Solution 1: Ignore source-mapping warnings (Easiest)
Add ignoreWarnings: [/Failed to parse source map/] to your webpack configuration.
E.g.
const { merge } = require('webpack-merge');
module.exports = (config) => {
return merge(config, {
ignoreWarnings: [/Failed to parse source map/]
});
};
Your webpack.config.js will look a lot different than this.
The idea is to add (or override) ignoreWarnings with the pattern of the message it should ignore.
Solution 2: Skip source-map-loading for culprit package (Cleanest?)
const { merge } = require('webpack-merge');
module.exports = (config, context) => {
return merge(config, {
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
use: [
{
loader: 'source-map-loader',
options: {
filterSourceMappingUrl: (url, resourcePath) => {
// #zxing has issues with its source maps
if (/#zxing/i.test(resourcePath)) {
return false;
}
return true;
}
}
}
]
}
]
}
});
};
The idea here is to override the source-map-loader rules and skip its execution if the current resource matches the regex. In my case, I want to skip any resource that contains #zxing.
I tried using hte exclude option but I had no luck with that and opted to use the filterSourceMappingUrl instead. Maybe it works for you though. Remember, the pathing has to be absolute so you might need to adapt the excluded pathings.
More details here
const { merge } = require('webpack-merge');
module.exports = (config, context) => {
return merge(config, {
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
use: ['source-map-loader'],
exclude: ['/node_modules/#zxing']
}
]
}
});
};
Hope this helps.
Cheers.
add react-app-rewired to your project:
yarn add --dev react-app-rewired
or
npm install react-app-rewired --save-dev
modify your package.json with those lines:
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
create a file called config-overrides.js in project root (same folder as package.json) with this content:
module.exports = function override(config) {
return {
...config,
ignoreWarnings: [
{
module: /node_modules\/stylis-plugin-rtl/,
},
],
}
}
change "stylis-plugin-rtl" in config-overrides.js above to whichever name of library that has an invalid build and throwing errors.
source maps errors should no longer appear.

mp3 files in Webpack 5 w/ Nextjs

I'm currently working with next#11.1.2 and webpack v5 and got stuck for hours with fixing mp3 loading. I tried several other solutions from stack and GitHub. None of them worked for me.
Type error: Cannot find module 'public/sounds/bighit.mp3' or its corresponding type declarations.
14 |
15 | // Assets
> 16 | import sound_bighit from "public/sounds/bighit.mp3"
| ^
info - Checking validity of types .%
Here is my last configuration for webpack:
const path = require('path')
const SRC = path.resolve(__dirname, 'public/sounds/')
module.exports = {
webpack: (config, { }) => {
config.module.rules.push({
test: /\.mp3$/,
incluse: SRC,
use: {
loader: 'file-loader',
options: {
name: '[name].[contenthash].[ext]',
outputPath: 'public/sounds/',
publicPath: 'public/sounds/'
}
}
})
// config.module.rules.push({
// test: /\.mp3$/,
// use: {
// loader: 'file-loader',
// },
// })
// config.module.rules.push({
// test: /\.mp3/,
// use: {
// loader: 'url-loader',
// },
// })
return config
}
}
There is no need to import such files. Next.js supports putting the assets in public folder. Remove your custom webpack configuration and then simply do this:
<audio controls src="/sounds/bighit.mp3" />
Refer: Static File Serving
Next.js can serve static files, like images, under a folder called public in the root directory. Files inside public can then be referenced by your code starting from the base URL (/).
Also, the error that you were getting was a TypeError, to fix it you can try:
// types/sounds.d.ts
declare module "*.mp3" {
const content: string;
export default content;
}
Refer: Importing Other Assets | TypeScript - webpack

How to use ng-annotate with hybrid app based on angular-cli

I'm working on an Angular.js project written with TypeScript. We're trying to evaluate whether to upgrade to Angular 8 and we're stuck with how to use ng-annotate with angular-cli's webpack configuration.
I believe that this can be achieved either by using the #angular-builders/custom-webpack tool or by using ngx-build-plus tool but I had not succeeded with neither of them.
My current attempt includes a partial webpack file for ngx-build-plus with the following configuration :
module: {
rules: [
{
test: /\.ts$/,
loaders: ['ng-annotate-loader?ngAnnotate=ng-annotate-patched'],
},
{
test: /\.tpl\.html$/,
loader: 'ng-cache-loader?-url&module=templates&prefix=src:./**/'
}
]
},
};
Having this, when I run ng serve --extra-webpack-config webpack.partial.js -o I get the following error : NonErrorEmittedError: (Emitted value instead of an instance of Error) error: couldn't process source due to parse error,Unexpected token
The token to which it refers, is simply the type declaration for a method parameter. So I'm guessing that there is some conflict with the loader that angular-cli already uses for TypeScript files but I don't know how to resolve this.
Is there any input on how to solve this either using one of the two tools or something else?
So, the way to do this is by using webpack-merge and custom-webpack.
This is the configuration to run ng-annotate with Typescript files :
module.exports = (config, options) => {
const customConfig = {
module: {
rules: [
{
test: /\.ts$/,
loaders: ['ng-annotate-loader?ngAnnotate=ng-annotate-patched'],
},
{
test: /\.tpl\.html$/,
loader: 'ng-cache-loader?-url&module=templates&prefix=src:./**/'
}
]
}
};
return merge.strategy({
'module.rules': 'prepend'
})(config, customConfig)
};
The key part is the merge.strategy call which will make sure that the loaders of the custom configuration will be prepended to the ones that angular-cli already sets up.
After several hours of looking at alternatives, the solution that worked the best for me was using babel-plugin-angularjs-annotate by:
Creating a new project
Installing babel and babel-plugin-angularjs-annotate
Executing babel, which takes the files from src, adds the annotations, and puts the result in the folder output.
For others needing the complete solution, this is what I executed:
mkdir babel-project && cd babel-project
npm init -y
npm install -D babel-cli babel-plugin-angularjs-annotate
Create .babelrc and add this:
{
"presets": [],
"plugins": [ "angularjs-annotate" ]
}
Finally execute babel:
npx babel src -d build --extensions .ts
This takes files like:
import * as _ from "underscore";
import "#app2/hello/chao"
const greeting = () => "Hello World"
angular.module("MyMod")
.controller("MyCtrl", ($scope, HelloClient) => {
HelloClient.add($scope, greeting);
});
And turns them into:
import * as _ from "underscore";
import "#app2/hello/chao";
const greeting = () => "Hello World";
angular.module("MyMod").controller("MyCtrl", ["$scope", "HelloClient", ($scope, HelloClient) => {
HelloClient.add($scope, greeting);
}]);
Update
Using babel-plugin-angularjs-annotate messed a lot with my formatting, so I ended up copying&pasting just the relevant parts of the Babel output, which took some hours.

Load images using React/Webpack

I set up the rule in webpack to load png images:
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'file?hash=sha512&digest=hex&name=[hash].[ext]',
'image-webpack?bypassOnDebug&optimizationLevel=7&interlaced=false'
]
}
That I found here: cannot load png files with webpack, unexpected character
Webpack seems to be working fine, giving no errors. So, I tried loading the png images paths that are located at app_folder/public/images/pca inside the render method:
importAll = (r) => {
return r.keys().map(r);
}
render() {
const pca_images = this.importAll(require.context('../public/images/pca',
false, /\.(png|jpe?g|svg)$/));
console.log('pca_images')
console.log(pca_images)
...
}
When I launch the app I do not see any errors but the pca_images is an empty array. The component itself is located at app_folder/views/. I tried loading the images also directly like that:
<img src={ require('../public/images/image1.png') } />
But whatever path I specify, it is just not working giving an error. I need to load all images from the folder app_folder/public/images/pca though, not just statically since I do not know the names of the images beforehand. Any suggestions would be greatly appreciated.
The solution that worked for me was to add the rule to the webpack.config.js:
{
test: /\.(jpe?g|gif|png|svg)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 10000
}
}
]
}
This rule I found here: ReactJS and images in public folder
Then I needed to run two commands in terminal:
npm install url-loader --save-dev
npm install file-loader --save-dev
And finally loading from the folder (see the question, render method) started working.

Trying to use css-loader with webpack to minimize our css

I've tried to go through a dozen or so different searches and read the docs on css-loader but I believe they aren't up to date.
I'm also trying to learn our react code and conventions coming from front end javascript / jquery so this is new for me.
What I want to do is take our css and minimize it using css-loader but I don't know how to do this from what I've read.
A piece of our current code looks like this - prod.config.js :
import webpack from 'webpack';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import PurifyCSSPlugin from 'purifycss-webpack-plugin';
import baseConfig from './base.config';
const PUBLIC_PATH = '//d1yepz0pwej23y.cloudfront.net/assets/' + process.env.TRAVIS_BUILD_NUMBER + '/';
export default {
...baseConfig,
output: {...baseConfig.output, publicPath: PUBLIC_PATH },
module: {
loaders: [
...baseConfig.module.loaders, {
test: /\.(woff|woff2|eot|ttf|otf|svg)(\?v=[0-9].[0-9].[0-9])?$/,
loader: 'file?name=[sha512:hash:base64:7].[ext]',
exclude: /node_modules\/(?!font-awesome)/
}, {
test: /\.(jpe?g|png|gif|svg)$/,
loader: 'file?name=[sha512:hash:base64:7].[ext]!image?optimizationLevel=7&progressive&interlaced',
exclude: /node_modules\/(?!font-awesome)/
}, {
test: /\.css$/,
loader: ExtractTextPlugin.extract('style', 'css?sourceMap!postcss'),
exclude: /node_modules/
}
]
},
plugins: [
// extract css
new ExtractTextPlugin('[name]-[chunkhash].css'),
// set env
new webpack.DefinePlugin({
'process.env': {
BROWSER: JSON.stringify(true),
NODE_ENV: JSON.stringify('production')
}
}), ...
...baseConfig.plugins
]
};
Is this enough to give me a suggestion on how to make this work? Or suggest where i can get some more info?
The docs say that I should require the css like this:
require("css-loader?minimize!./file.css")
but I'm not sure how to implement.
Thanks!
Update:
So after trying out what #Brandon mentioned, I actually saw code in our entry already that require's the css file.
if (process.env.BROWSER) {
require('styles/app.css');
}
I updated that to:
require('css-loader?minimize!styles/app.css');
but ended up with this error:
ERROR in ./~/css-loader?minimize!./app/styles/app.css
Module build failed: CssSyntaxError: /css-loader!/Users/homeImac/workspace/node_modules/style-loader/index.js!/Users/homeImac/workspace/node_modules/css-loader/index.js?sourceMap!/Users/homeImac/workspace/node_modules/postcss-loader/index.js!/Users/homeImac/workspace/app/styles/app.css:5:1: Unknown word
but that word is #import, does this make sense? If you guys can enlighten me on why this error is appearing, I'd appreciate it.
Thanks again!
So after trying to find solutions that solve the problem with loaders, I decided to look for another solution. A plugin called Purify CSS Plugin ended up being the answer.
new PurifyCSSPlugin({
purifyOptions: { info: true, minify: true }
})
Using the loader brought on a 'unknown word' error. Everything I tried either shifted the unknown word or did nothing to change the situation. All the folks online seemed to not be able to overcome this issue either.
Just proves the fact that there is usually more than one way to fix a problem.
put that require statement in one of your app's JavaScript source files. If it is a "global" css file, then your app's main entry JS file is a good candidate.
e.g. in app.js:
require("css-loader?minimize!./file.css"); // tell webpack about your css dependency so it can load and minimize it

Resources