Tutorials on Quick Help

Learn about Quick Help from fellow newline community members!

  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL
  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL

How to Fix the Error Error:error:0308010C:digital envelope routines::unsupported

If you are running Webpack or a CLI tool that’s built on top of Webpack (e.g., react-scripts for Create React App applications or vue-cli-service for Vue applications) with version 17 of Node.js, then you may have come across the following error: With Node.js v17+ supporting OpenSSL 3.0 , algorithms like MD4 have been relegated to OpenSSL 3.0’s legacy provider. A provider is a collection of cryptographic algorithm implementations. OpenSSL 3.0 comes with five standard providers : default, legacy, FIPS, base and null. The legacy provider consists of algorithms that are considered to be rarely used in today’s world or unsafe security-wise. This provider exists for backwards compatibility purposes (for software that still rely on these algorithms) and is not loaded by default. Webpack creates hashes using the crypto.createHash() method of the Node.js crypto module. This method can only create hashes with algorithms that are available and supported by the version of OpenSSL corresponding to the currently installed Node.js version. Since Webpack specifies to the crypto.createHash() method to use the MD4 algorithm (see below code), and this algorithm is not readily available in Node.js v17+ due to OpenSSL 3.0 not loading legacy providers by default, Webpack errors out and Node.js logs the error message Error: error:0308010C:digital envelope routines::unsupported . ( https://github.com/webpack/webpack/blob/main/lib/util/createHash.js ) To fix this error, you can do one of five things: If you are running Node.js via nvm , then you can install Node.js v16. Once the installation finishes, nvm automatically switches the current version of Node.js to the newly installed version of Node.js. Note : Specifying 16 installs the latest LTS version with a major version of 16, which happens to be, as of the publication of this article, 16.16.0. Note : The Node.js version can be any version less than 17, but it's highly recommended to stick with Node.js versions that are under active or maintenance LTS status . Run node -v && npm -v to verify the versions of Node.js and npm running on your machine. Then, delete the node_modules folder and re-install the project's dependencies. Similarly, if you are running Node.js via Volta , then you can also install Node.js v16 the same way. Note : For convenience, you can save this exact version of Node.js and npm to the project via the volta pin node@16 command. Anytime you enter the project directory and run Node.js, Volta automatically switches the current version of Node.js to the pinned version of Node.js. Run node -v && npm -v to verify the versions of Node.js and npm running on your machine. Then, delete the node_modules folder and re-install the project's dependencies. Introduced in Node.js v17 alongside support for OpenSSL 3.0, the --openssl-legacy-provider flag tells Node.js to revert to OpenSSL 3.0's legacy provider. This allows you to run tools like Webpack that still create hashes with legacy cryptographic algorithms like MD4. Here are some examples of how to pass this flag: If you have multiple CLI tools that depend on legacy cryptographic algorithms, then you can set the NODE_OPTIONS environment variable to --openssl-legacy-provider instead of passing the --openssl-legacy-provider flag to each of these tools. For MacOSX and Unix, run the following command before running anything else: For Windows, run the following command before running anything else: Alternatively, you could set the environment variable directly within an npm script of a package.json file, like so: With npm-run-all , all of the executed npm scripts receive the NODE_OPTIONS environment variable. Note : For cross-platform compatibility, set the environment variable via a CLI tool like cross-env . For an older Create React App project that runs react-script v4.0.3 (the version before v5.0.0 ), there are three files across two dependencies that use the MD4 algorithm for creating hashes: Upon patching these files, the Create React App application runs successfully with Node.js v17+. However, this approach is highly discouraged. You would need to: For a Webpack project, you can apply the following patch to redirect requests for creating hashes with the MD4 algorithm to creating hashes with the MD5 algorithm instead, like so: ( https://github.com/webpack/webpack/blob/main/lib/util/createHash.js ) Note : Overriding the createHash() method of the crypto module via the above solution was originally suggested by Alexander Akait , a core contributor of Webpack. For Create React App projects, check the installed version of react-scripts . If the version is less than v5.0.0, then upgrade the version of react-scripts to v5.0.0 or higher. In v5.0.0 of Create React App, the version of the cached Webpack modules and chunks gets generated using a stringified object of environment variables and MD5 algorithm . ( https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/config/webpack/persistentCache/createEnvironmentHash.js ) Want to learn about Vue 3, the Composition API and building real-world, production-ready applications with Vue 3? Check out our book Fullstack Vue 3 :

Thumbnail Image of Tutorial How to Fix the Error Error:error:0308010C:digital envelope routines::unsupported

What Happened to the FC Type's Implicit children Prop in @types/react v18?

In @types/react v18, the implicit children prop was removed from the FC type. According to a pull request for @types/react , this prop was supposed to be removed in @types/react v17, but was postponed to @types/react v18 so that developers can easily upgrade their React applications to v17 with few to zero problems . Assuming React v18 and @types/react v18 are both installed within a React project, and given the following code for a component that accept children as a prop... TypeScript raises the following error: The implicit children prop from the FC type ended up being removed for consistency; TypeScript should always reject excess props. Therefore, to resolve this error, manually (and explicitly) define the children prop in the component's props interface, like so: Here's a CodeSandbox demo that demonstrates both the problem and solution: https://codesandbox.io/embed/removal-implicit-children-test-xdfdpl?fontsize=14&hidenavigation=1&theme=dark Note : You may notice that PropsWithChildren still exists within the type definition file, and you may be tempted to use it to resolve this error. However, this prop is kept around for backwards compatibility purposes and for a specific codemod . If you want to learn more advanced techniques with TypeScript and React, then check out our Fullstack React with TypeScript Masterclass :

Thumbnail Image of Tutorial What Happened to the FC Type's Implicit children Prop in @types/react v18?

I got a job offer, thanks in a big part to your teaching. They sent a test as part of the interview process, and this was a huge help to implement my own Node server.

This has been a really good investment!

Advance your career with newline Pro.

Only $30 per month for unlimited access to over 60+ books, guides and courses!

Learn More

Should I Directly Access Data From the Apollo Client or From React Component State?

Consider the following code snippet of a React component, <App /> , that... You may have noticed that the data sent back by the mutation provides the user's information in a logIn field, and any data returned from a successful mutation automatically gets added to the local Apollo Client cache. Therefore, why do we have a user state variable when we could just access the user's information via the data field in the mutation result object? For example, like this: This can be considered an anti-pattern, but data can be either undefined or { logIn: { id: ..., token: ..., ... } } . Therefore, you would need to check if data is undefined or not directly in the body (and rendering section) of the <App /> component. Even after you determine that data is not undefined , you would still need to perform the same number of checks as before for the logIn property, etc. By using the setUser approach, you start with a baseline user object with its properties initialized to null , so you don't have to check if the user is undefined in the body (and rendering section) of the <App /> component (one less check). Additionally, with this approach, you only perform the checks for the data inside the onCompleted function. You could directly access the cache via the update function, which is called after the mutation completes and provides the cache as an argument, like so: However, the cache at this point doesn't actually have user data in the cache (to confirm this, print JSON.stringify(cache.data.data) in the update function). The user data is provided separately as the update function's second argument. You would need to manually modify the cache so that it has this user . Once the cached data is updated, the change gets broadcasted across the application and re-renders the components with active queries that correspond to the updated data. So you would need to put into each component that relies on user a call to useQuery that fetches the user . On initial page load, it's an extra, unnecessary network request since the LOG_IN already gets us the user data. But after the initial page load, if the user decides to log in or log out, then getting the user will be based on the update to the cache and having its updated user data be broadcasted to the useQuery s. In this case, it's more ideal to use setUser if it means one less network request on initial page load. As always, it's completely up to you how you want to manage state in your applications, but be sure to evaluate the trade-offs for each possible solution and pick the one that best suits your situation. Check out this Codesandbox example to see what I mean: https://codesandbox.io/embed/mutations-example-app-final-tjoje?fontsize=14&hidenavigation=1&theme=dark If you want to learn more advanced techniques with TypeScript, GraphQL and React, or learn how to build a production-ready Airbnb-like application from scratch, then check out our TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL :

Thumbnail Image of Tutorial Should I Directly Access Data From the Apollo Client or From React Component State?

Find and RegExp Match - How to Fix Object is possibly 'undefined' and Object is possibly 'null' Errors in TypeScript

Consider the following TypeScript code snippet: Let's assume that the list of cars is fetched from a remote API service. In this TypeScript code snippet, we... However, there are two problems with this TypeScript code snippet: As a result, TypeScript gives you the warnings Object is possibly 'undefined' for the find() method and Object is possibly 'null' for the subsequently chained match() method. To keep method chaining possible, we need to provide default values that ensures chained methods never get called on undefined and null values. Here's what this solution looks like: This solution may look compact and will save you a few bytes, but at the same time, you sacrifice readability. This can be taxing for less experienced developers who are unfamiliar with some of this syntax. By breaking up the method chaining into multiple statements, developers can better understand what exactly is happening with the code, step-by-step. Additionally, you can add more concrete checks to ensure that the code is even more type-safe. Here's what this solution looks like: If you want to learn more advanced techniques with TypeScript and React, then check out our Fullstack React with TypeScript Masterclass :

Thumbnail Image of Tutorial Find and RegExp Match - How to Fix Object is possibly 'undefined' and Object is possibly 'null' Errors in TypeScript