CRA Webpack Dependency Optimization - reactjs

Does Create-React-App (or Webpack used by Create-React-App) at any stage (development, staging or production) optimise your node_modules? That is, if I had an import like this:
import _ from 'lodash'
and only use the map function in my project. Would my build bundle for production have all of lodash or would it strip out all other functions and keep the ones that are being referenced in my code?

CRA use UglifyJsPlugin in the webpack.config.prod.js which supports dead code removal.
But you should only import what you need for this to work: https://webpack.js.org/guides/tree-shaking/

For anyone who stumbled here in 2021, create-react-app also do tree-shaking when you use import * as _ from 'lodash

Related

How to perform tree shaking for lodash in a create-react-app project?

I need to perform tree-shaking to reduce bundle sizes where lodash and some other libraries are being used.
I've converted all lodash imports like this:
import {isEmpty} from "lodash";
But still bundle size is not getting reduced.
To use plugins like 'lodash-webpack-plugin', we need to configure in webpack.config.js, which is not possible in a create-react-app project. I tried using react-app-rewired but getting issues like:
screenshot of error
Following versions are being used in the project:
react-scripts: 3.4.1
webpack: 4.42.0
react: 16.13.1
lodash: 4.17.15
Webpack can perform tree shaking automatically when ES6 modules(import/export syntax) are used.
Looks like lodash is built to use Common-JS modules.
So you can use single export and cherry-pick methods to reduce size of bundle:
import isEmpty from "lodash/isEmpty";
With this import, only isEmpty function will be included in your bundle.
Alternatively, you can try to use lodash-es written in ES6

Modify module resolver when using create-react-app

I want to avoid using relative pathing when importing other files. For example, I'd like to change something like:
import InputBar from ../../pages/InputBar
to
import InputBar from components/pages/InputBar
Normally I would modify the resolve options in webpack, but I'm using create-react-app and don't have access to it.
I would like to avoid using npm run eject. Is there another way to avoid using relative pathing for imports?
You can use rewired which will give you access to configuring react-scripts to your liking and not having to eject from CRA.

Should we install react and react-dom in --save or --save-dev mode?

Some tutorials use --save mode while some use --save-dev mode.
Both of them use Babel, saying that it is used to convert React into plain Javascript that browsers understand. That means the final bundle will have Javascript. In that case why do we need to install react and react-dom in --save mode? --save-dev mode should suffice right?
Also, statements like import React from 'react', do they go into prod build bundle files? If not, how are statements like React.createClass work without React being available in that corresponding scope/memory-space?
--save mode is for packages that your app will use when it's running, like React. --save-dev are for packages that help you develop like linters, module bundlers, transpilers (eg Babel).
This separation is almost entirely for your benefit -- putting everything into your main dependencies with --save won't break anything, but it's considered bad organization.
By the way, NPM 5 and above will automatically save packages, so the --save flag isn't necessary anymore. (You still need to use --save-dev to mark packages as a "development dependency").
Also, statements like import React from 'react', do they go into prod build bundle files? If not, how are statements like React.createClass work without React being available in that corresponding scope/memory-space?
Yes, that import React from 'react' ends up in the bundle, but using a regular JavaScript function instead of an import statement. You can open up the bundle file in your text editor to see what your code has been transformed into.

Working with sass and react

I am learning React and I have already created a few apps with CRA.
I haven't found a good and easy way to include sass on my react projects so I came up with this:
install node-sass on the src folder
add this to the package.json:
"node:sass": "node-sass src/index.scss src/index.css -w"
then on each component, I would add a sass partial file, so I could keep the style and the js file in the same folder.
is there any problems with doing that?
I've read some tutorials to config webpack to use sass but it sounded to complicated.
Including partials per component is just fine and actually encouraged as a standard. Then you include it in the webpack with the ExtractTextPlugin, which allows you to bundle all your sass files into a single css file that you import in index.html. You can see an example here: https://github.com/ianshowell/react-serverless-kickstart/blob/master/webpack.common.js#L46
For this to work, you also need to include the sass-loader which will let your Js files parse your Sass class names. Feel free to use my starter pack that the above code is linked in to help you figure it all out.
Edit: Also, take a look at this example component to see how importing styles works: https://github.com/ianshowell/react-serverless-kickstart/tree/master/src/components/TodoItem
If you want to use sass in your react app, install chokidar
It will help you:
https://www.npmjs.com/package/react-scripts-sass-chokidar
Create react app v2, support SASS out of the box (https://reactjs.org/blog/2018/10/01/create-react-app-v2.html)
Here a link to read the documentation: https://facebook.github.io/create-react-app/docs/adding-a-sass-stylesheet#docsNav
All you need is to install node-sass if not already
npm i node-sass --save-dev
And then make sure you import files with scss extension.
If you need to change old css files, change the extension, and so follow with the imports.

React using import vs. required

I am currently learning react and I have an app using webpack, babel and react. It seems react has two ways of writing it using either required or import. It also seems there is a lot more documentation on using import. How can I change my stack to use the import version?
The import and export statements are an ES6 standard. Right now, your setup is likely using Babel to transpile this into ES5. You can use one or the other, but import/export will soon become the standard, so adopting it is advised.
import is ES6 (or ES2015) standard. To use it, you need to install and activate the preset in babel.
Follow these steps:
Go to your project folder then type this: npm install --save-dev babel-cli babel-preset-env
Create a file named .babelrc (in case you have not created one) and insert this lines:
{
'presets': ['env', 'react']
}
I assume you have setup the webpack to work with babel.

Resources