Critical dependency warning when using react-pdf - javascript

I'm trying to display a pdf on a react application and i get the following warning:
/node_modules/react-pdf/node_modules/pdfjs-dist/build/pdf.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
Vscode tells me this under the import function.
Could not find a declaration file for module 'react-pdf'
Already tried running npm install, npm install react-pdf and reinstalling the package
import React, { Component } from 'react';
import { Document } from 'react-pdf';
import sample from 'file location'
export default class viewer extends Component {
render() {
return (
<div>
<Document
file={sample}
onLoadSuccess={this.onDocumentLoadSuccess}
>
</Document>
</div>
);
}
}
Displays:
"Failed to load PDF file" in the browser

This code will display your pdf file, but issue will display in IDE console.
import { Document, Page, pdfjs } from "react-pdf";
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
In my case I'm using webpack 4 and it's not supportted yet.
If you build project it will work fine.

My full workaround.
Create a file at the root called config-overrides.js and it should contain the following:
module.exports = function override(config) {
config.module.rules[0].parser.requireEnsure = true
return config
};
After that npm i react-app-rewired to you app and change your build function in package.json to read react-app-rewired build/react-app-rewired start.
That should do it for now.

Related

how to import mathjax in vue as local dependency?

im using vue-mathjax in my project and in the readme it says to use cdn of mathJax
works fine with the CDN version
im need to use mathJax(v. 2.7.2) as local as dependency for my project but dont know how to import it with the correct configurations
how do yout set the configuration same as with the cdn version?
CDN
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-AMS_HTML"></script>
Local import after installing with npm
//main.js
import '../node_modules/mathjax/MathJax?config=TeX-AMS_HTML'
error
Uncaught SyntaxError: Unexpected token '<'
repo - https://github.com/qwtfy/mathjax-test
If you're able to switch to the new version 3, here are the steps assuming you already have vue-mathjax.
Install MathJax from npm: npm install mathjax#3
Move the MathJax's es5 directory to a public directory: mv node_modules/mathjax/es5/ src/assets/mathjax/
Import the component config you want, for example:
import '../assets/mathjax/es5/tex-chtml.js';
If you must stick with version 2.7.x, you'll need to do the following. In my testing, it was less stable.
Install MathJax 2.7.9 from npm: npm install --save mathjax#2.7.9
Move MathJax.js (located at node_modules/mathjax/MathJax.js) to a public directory like assets.
Move TeX-AMS_HTML.js (located at node_modules/mathjax/config/TeX-AMS_HTML.js) to the same public diretory.
Import both files inside your component, in order:
import '../assets/MathJax.js'
import '../assets/TeX-AMS_HTML.js';
Here it is working for me:
Full single file component example using v3 and vue-mathjax.
<template lang='pug'>
div
b-container(style='width: 40%')
b-textarea(v-model='formula' cols='30' rows='10')
p output
vue-mathjax(:formula='formula')
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { VueMathjax } from 'vue-mathjax';
import '../assets/mathjax/es5/tex-chtml.js';
#Component({
components: {
'vue-mathjax': VueMathjax,
},
})
export default class HelloWorld extends Vue {
formula = '$$x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.$$';
}
</script>
Documentation of these steps can be found here and here.

react helper import fails in production but works in development

I've got a file called "globalHelper.js" like this:
exports.myMethod = (data) => {
// method here
}
exports.myOtherMethod = () => { ... }
and so on...
I import my Helper in other files like this:
import helper from "../Helper/globalHelper";
Now there is the problem:
In the past, everything worked with that when running my build-script:
"build": "GENERATE_SOURCEMAP=false react-scripts build"
but for some reason, when I run "npm run build", I get the error:
Attempted import error: '../Helper/globalHelper' does not contain a default export (imported as 'helper')
However, when I simply start my development server (npm start), everything works just fine.
I already tried to import like import { helper } from "../Helper/globalHelper";, but that did not work either.
Does someone know how to solve that?
try exporting like this with ES6 syntax
export const myOtherMethod = () => { ... }
then
import { myOtherMethod } from '...your file'
The method you are using exports.functionName is CJS. you need to use require to get the methods.
The CommonJS (CJS) format is used in Node.js and uses require and
module.exports to define dependencies and modules. The npm ecosystem
is built upon this format.
If you want to use module method you can do this.
export { myOtherMethod1, myOtherMethod2 }
then you import like this.
import * as Module from '....file name'
Since you've not export default you should import the function with {} like :
import {helper} from "../Helper/globalHelper";

Vue component not loaded with Plugin syntax

I have this Vue plugin that is not working:
import _Vue from "vue";
import particles from "./Particles.vue";
const VueParticles = (Vue: typeof _Vue, options: unknown) => {
_Vue.component('Particles', particles);
};
export { particles as ParticlesComponent };
export default VueParticles;
It builds, but if I try to use it, it doesn't load the component and the app returns me this error:
[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> at src/App.vue
And I load the plugin like this:
import Particles from "particles.vue";
Vue.use(Particles);
But if I load the component using the Vue.component syntax, it's working, like this:
import { ParticlesComponent } from "particles.vue";
Vue.component("Particles", ParticlesComponent);
This is the template I'm using:
<Particles id="tsparticles" :options="options" :particlesInit="particlesInit" :particlesLoaded="particlesLoaded"/>
You can try to replicate the issue following these steps:
Clone tsParticles dev branch with: git clone https://github.com/matteobruni/tsparticles.git --branch dev
Run yarn && npx lerna bootstrap && npx lerna run build
Go to demo/vue folder
Run yarn serve and open http://localhost:8080, everything should work (an animated background should start animating)
Edit src/App.vue commenting the working Vue.component and restoring the Vue.use
Rerun yarn serve and open http://localhost:8080, the background this time is not appearing
I just switched from yarn workspaces to standard yarn for big issues with the node dependencies in the whole project
I don't understand why it broke like this.
I also tried an external Vue.js app instead of the demo one inside the project but nothing changed.
The component is using vue-property-decorator but I tried switching to the Vue.extend syntax and nothing changed so I reverted to the previous class code.
The plugin file should be exporting an object with an install function, but your plugin just exports the function itself. Also, the install function's argument should be used in the body (i.e., Vue is the argument name, so the body should contain Vue.component()).
The fix should look like this:
const VueParticles = {
install(Vue: typeof _Vue, options: unknown) {
Vue.component('Particles', particles);
}
};
export default VueParticles;

Next.js with FortAwesome and SSR

I am building a Next.js application and looking for an icon package that works with its SSR paradigm.
After trying a few libs, I'm now working with FortAwesome/react-fontawesome, which looks promising.
The problem is when the page loads the icons are large (unstyled) and then suddenly they are styled properly. I'm trying to figure out how to get these to style server-side.
I've seen folks talk about importing a stylesheet provided by FortAwesome:
import '#fortawesome/fontawesome-svg-core/styles.css';
However, I'm unsure which file(s) this should be done in and also, Next complains when I try this:
[ error ] ./node_modules/#fortawesome/fontawesome-svg-core/styles.css
1:8 Module parse failed: Unexpected token (1:8) You may need an
appropriate loader to handle this file type, currently no loaders are
configured to process this file
I've looked at the CSS plugin, but this also seems like a red herring.
How can I get the font-awesome icons in this package to be styled on the server with Next.js?
React-fontawesome has added a section on how to get FontAwesome working with Next.js.
https://github.com/FortAwesome/react-fontawesome#nextjs
Create an ./pages/_app.js file in your project
import React from 'react'
import App, { Container } from 'next/app'
import { config } from '#fortawesome/fontawesome-svg-core'
import '#fortawesome/fontawesome-svg-core/styles.css' // Import the CSS
config.autoAddCss = false // Tell Font Awesome to skip adding the CSS automatically since it's being imported above
class MyApp extends App {
render() {
const { Component, pageProps } = this.props
return <Component {...pageProps} />
}
}
export default MyApp
or using a function component:
import { config } from '#fortawesome/fontawesome-svg-core'
import '#fortawesome/fontawesome-svg-core/styles.css' // Import the CSS
config.autoAddCss = false // Tell Font Awesome to skip adding the CSS automatically since it's being imported above
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
There are definitely a few ways to take this problem. I solved it in my project by importing the icons I needed directly into my React app. So no Font Awesome libraries sit on the client-side, just the rendered SVGs.
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faAdobe } from '#fortawesome/free-brands-svg-icons/faAdobe'
...
return (
<FontAwesomeIcon icon={faAdobe} />
)
Font Awesome also provides a page to discuss other methods: server-side-rendering
I'm going to put this as an answer, because it's a way, however I feel like there is a better solution out there, so I will not accept this one.
I created a static/css folder, then copied the css file referenced in the question
cp node_modules/#fortawesome/fontawesome-svg-core/styles.css static/css/fortawesome.css
Then in _document.js I load the file via link tag:
<link
rel="stylesheet"
type="text/css"
href="/static/css/fortawesome.css"
/>
I would consider this a stop-gap solution. One issue obviously is that when the underlying library updates I would need to copy over the latest version of the css file manually.
I had this same issue and fixed it by manually inserting Font Awesome's CSS into styles which I know will get SSR'ed correctly.
I use styled-components, which is easy to set up with Next.js SSR, and here's how I did it:
import { createGlobalStyle } from "styled-components";
import { config, dom } from "#fortawesome/fontawesome-svg-core";
// Prevent FA from adding the CSS
// (not that it was doing it in the first place but might as well)
config.autoAddCss = false;
// Add the FA CSS as part of Global Styles
const GlobalStyles = createGlobalStyle`
${dom.css()}
`;
Here is what I have tried so far to fix this issue in my project:
Installation of #zeit/next-css, #zeit/next-sass [I need sass too.]
Installation of fontawesome packages & import CSS
Installation of #zeit packages
Install required packages:
npm i --save #zeit/next-css
npm i --save #zeit/next-less
npm i --save #zeit/next-sass
then update next.config.js file such as below that will support CSS import which fix the issue of loading correct styles upon loading:
const withCSS = require('#zeit/next-css')
const withLess = require('#zeit/next-less')
const withSass = require("#zeit/next-sass");
module.exports = withLess(withCSS(withSass({
webpack(config, options) {
config.module.rules.push({
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
use: {
loader: 'url-loader',
options: {
limit: 100000
}
}
});
return config
}
})));
Installation of fontawesome packages & import CSS
Install required packages:
npm i --save #fortawesome/fontawesome-svg-core
npm i --save #fortawesome/free-solid-svg-icons
npm i --save #fortawesome/react-fontawesome
Then you can use following code within your pages extending React.Component located under pages directory:
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { library } from '#fortawesome/fontawesome-svg-core';
import { fas } from '#fortawesome/free-solid-svg-icons'
import '#fortawesome/fontawesome-svg-core/styles.css';
library.add(fas);
Then this is the way you can use fonts:
<FontAwesomeIcon icon={["fas", "user-tie"]} />
I may be wrong.

How can I make webpack treeshake my ES6 module?

I have followed every guide out there for turning on tree shaking in webpack 4 but webpack still bundles code from a NPM module that I have set up to be treeshaken. How can I enable treeshaking and not include particular code in my web app?
Full source code in GitHub repo
I have a CRA (create-react-app) that imports a NPM module I created to test it that looks like this:
package
index.mjs
dist
esm
components
image
index.js
index.js
index.js
with package.json like this:
"main": "index",
"module": "index.jsm",
"sideEffects": false,
that transpiles using babel with babelrc like:
{
"presets": [
[
"#babel/preset-env",
{
"modules": false
}
],
"#babel/react",
"#babel/flow"
]
}
I have 3 React components: image, avatar (that imports image) and login-button that has this es6 code:
import React from 'react'
document.body.innerHTML = document.body.innerHTML + "<div>This is a side effect and should never have happened</div>"
export default () => <button>Login</button>
The index file for the NPM es6 module:
import * as lib from './dist/esm'
export default lib
In the CRA's app.js I have:
import TreeshakingTestModule from 'treeshaking-test-module'
function App() {
return (
<div className="App">
<TreeshakingTestModule.Avatar />
</div>
);
}
When I npm start it builds and renders the avatar but I also see the message.
Note that login-button is never used however the default export of my NPM package which does export the component is imported, however I read tutorials that explained that even default exports and re-exports should still work with tree shaking if what is exported is never used.
What is happening? What am I doing wrong?
Full source code in GitHub repo
As far as I know, webpack three shakes by analysing imports statically, not by reading your code. You cannot expect webpack to realize you're only using Avatar from TreeshakingTestModule.
So you need to declare what you want to use at import level, by using named imports and exports:
import {Avatar} from 'treeshaking-test-module'
function App() {
return (
<div className="App">
<Avatar />
</div>
);
}
So webpack knows you're only using the Avatar export.
This means that Avatar needs to be a named export in your treeshaking-test-module module.

Categories

Resources