Webpack build vs react-scripts build - reactjs

Say the webpack config is as follows
{
entry: path.join(__dirname, 'src', 'index.js'),
output: {
path: path.join(__dirname, 'build'),
filename: 'bundle.js'
},
Now the build from webpack is
and the build from react-scripts build ( static contains css, js and media in seperate folders )
Question: Is there any specific advantage of webpack over react-scripts build? ( including but not limited to performance )
NOTE: package.json is edited to achieve this.

Webpack is a general purpose bundler, with applications beyond React. Before create-react-app, the web was full of examples of setting up a brand new React project which uses webpack as the bundler. It is extremely flexible and can handle things including and beyond what a React application would need. It works for Angular, Vue, NodeJS and even Web Assembly.
But it used to take a while to setup. You will need to understand its working and configure it so that you can transpile your React+ES6 code into plan-vanilla JS. You would need to decide the output structure you like and configure webpack for it. And then also add hot-module-reloading and code-splitting support yourself. During this, you will also need to add other plugins required by Webpack to support all the above :).
This naturally caused some fatigue with folks who were starting with React.
So facebook created cra which internally uses webpack, pre-configured to include all the nice tools to take care of these basics and help you focus on the React part of your code. It hides webpack from you as much as possible, otherwise the build process may break if the configuration is changed by the user.
With that aside, the structural conventions which cra uses should not be having any performance impact over a bare-bones webpack setup. It's just a convention.
Your question should then be, when would I use create-react-app and when would I use Webpack?
As a beginner you might want to stick to cra as you focus on your react app. Eventually there would come a time where what you want to do is not supported by the webpack configuration cra is managing under the hood. A very common example is if you want to write a component library to reuse in other apps. This cannot be done by cra (it's about the whole app :)). You can then switch over to webpack and start learning it.

react-scripts hides all of the webpack configs behind the scenes. The advantage of this is it makes it cleaner and since create-react-app is regularly updated, its easy to stay up to date with React, Webpack, and Babel. The community automatically fixes the issues for you.
In terms of performance, should be the same regardless with react-scripts or with webpack.
Advantages of running only webpack:
Full control of your environment
Can do custom things like server-side rendering easily (still possible with create-react-app
Knowledge of webpack as a skill
Disadvantages of webpack only
Full in charge updating and maintenance of webpack (some webpack versions are not backward compatible or future compatible)
Can be intimidating and can be a headache if you are trying to learn to react quickly.
If you want to customize create-react-app, here is some info
https://auth0.com/blog/how-to-configure-create-react-app/
Here is server-side rendering with create-react-app
https://hackernoon.com/server-side-rendering-with-create-react-app-1faf5a9d1eff
TLDR: Use create-react-app / react-scripts if you want to go to 0-100 as quick as possible for whatever reason
Use just webpack if you enjoy messing around under the hood

Related

how much advantage does a webpack created from scratch give?

I created an application using create react app, then I did the npm run eject command and I get a list of all dependencies. Yes, I do not have webpack config files, which will be if I create my own webpack. I see only one advantage that create react app adds extra dependencies that are not needed. All other settings, as I understand it, I can add the cra application to my own webpack. Can you please tell me why it is so important to create your own webpack? I just don't see much difference between builds. I have read a lot of articles and have not found objectively strong advantages can you tell me

Should we bundle shared component library separately in lerna monorepo?

I have three packages inside standard lerna monorepo.
client
react library
core
Core - is a shared component library with some utils (may or may not publish on npm).
React library is component library which will be shared on npm.
client is a bundled js library which will be consumed in browser with static html files.
core is a dependency in react-lib as well as client
Question 1 - How to setup core, should I transpile with tsc and bundle with tools such as rollup or vite (i personally prefer vite/rollup over webpack). or just leave it as is and import it in client and react-lib with absolute paths like 'core/src/*"?
Question 2 - can i build core in 'es' format and build client just like normal react app with either cra or vite. I tried this but i think i am missing something as final bundle doesn't seem to work in browser.
Any help would be really appreciated.
You have a few questions and I might not be able to answer them all but hopefully enough to guide you for the solution you're looking for.
Core - is a shared component library with some utils (may or may not publish on npm).
If you want to use Lerna then I guess you'll have to eventually publish the package on npm or a private repository. As an alternative, you could also use pnpm workspaces and their workspace: protocol which will allow you to link the packages in your workspace (monorepo) without ever downloading them from npm, for example if you use workspace:* then it will always use and link to the latest code from your local workspace. You could also use workspace: protocol with Lerna (or Lerna-Lite) since they both support it.
For your next Questions, I'll answer the last part of your Question 1 first because that affects the other portion of the question.
Question 1: ...or just leave it as is and import it in client and react-lib with absolute paths like 'core/src/*'?
Use absolute paths outside of the package is not a good thing to do since it will only work on your local project and you cannot publish that to npm since it will be broken for the other users. It's better to stick with the workspace and let the package use the main or exports entries defined in your package.json. In other words, it's preferable to always build/transpile and let your other package use the transpiled code and if you need to debug then make sure to also include sourcemap
Question 1: How to setup core, should I transpile with tsc and bundle with tools such as rollup or vite (i personally prefer vite/rollup over webpack)
It probably doesn't matter which one you use TypeScript, Rollup or WebPack, In one of my project I use TypeScript in watch mode, it will auto-transpile whenever you change your code, the downside is that the more packages you have then the more TypeScript threads are opened in watch mode (1x per package) but in your case if you only have 3 then it's fine, there's also this TypeScript issue that I'm following which will hopefully bring multi-threaded compilation in the future. You could also use Rollup and the concept would be the same, use it in watch mode for each package (I've done it with Vite/Rollup using vite build --watch
as explained in the next paragraph).
You can take a look at a project I've done Vue 3 and pnpm workspace using pnpm workspace with the workspace: protocol, it uses Rollup for transpiling and also uses Vite library mode which allows to bundle your library for distribution (on npm or others...), this allows you to bundle each package as a lib that is easily reusable by other projects. It's a Vue 3 project, so it's not a React project but it should give you enough ideas on how to do in React and it should help to answer your Question 2. Also that project is not using Lerna/Lerna-Lite but since it uses the workspace: protocol then it would be super easy to add Lerna on top of it in the future (basically just adding the lerna.json config should be enough)

What are the benefits of using webpack on electron?

I'm thinking about an app that uses electron, react and webpack. But I'm not sure if it make sense to use webpack on electron. I'm definitely sure that using webpack to the react part of an app could benefit a lot but I would like to know if it is the same thing with the electron part of an app.
Why do you need webpack for some cases even in node.js? Because CJS module resolution can cost a lot depends on your code:
https://twitter.com/samccone/status/1010584941355077632
Friendly reminder that Node startup time due to module runtime parse and compile is non-trivial. Illustrated below is the hello-world webpack common chunks example, As we can see the actual work takes < 1/4th of the time, the rest is lost to the javascript parse ghoul
This applies to Electron because it shares the exact same module resolution.
https://twitter.com/_ojkwon/status/933046538762207232
CJS without bundling
with webpack bundled
Still, it means development / deployment pipeline will change entirely, and this is not the guaranteed path of improving cost of module loading. You have to analyze your dependencies, and decide proper path for best performance.
Webpack is separate from electron. Webpack is used to bundle js files if you want to bundle your code together. There is a similar question that goes into additional detail here.

Is adding Webpack to finished project (React.js) a good practice?

I'm starting journey with React and have a very important question for me : as I'm not familiar with Webpack can I add it later - after I finish my project? Won't it cause any problems in file structure and so on ?
You could add webpack once your project is complete, but this isn't really good practice.
Webpack allows you to work in ways which would not be possible without such a tool. Webpack does lots of things, but most of the things which it does are useful when you're developing code, not once you're done developing. If you were to do add webpack once you've finished your project, you would have set up your code in a way which doesn't take advantage of webpack.
For React, webpack makes it easy to split your components into multiple files, and it allows you to transform files containing jsx.
Webpack can be a pain to configure, but there are options to make your life easier, like create-react-app. Alternatively, parcel has a lot of the functionality of webpack, without the config.

Migrate gulp process to include typescript

I am updating the build process for an Angular 1.5.8 application, to allow development on Typescript.
After an over-complicated experience with Grunt, the current build process is simple and only uses Gulp and Browserify to build two bundles: my-lib.js and my-app.js. This way, the library, which is bigger, but more stable than my application code, doesn't have to compile so often and the compilation of the application-domain code only takes 0.1 sec. I am happy with that -- as well as the other developers.
Now we are looking forward to migrate to Angular 2.0 and want to start development in Typescript, but I'm not sure on how to integrate it on the build process and even the best approach on how to do it: should it be preferred to use tsc only to compile Typescript into Javascript and let Browserify handle the dependencies? Or should I use tsc as my main build tool and let it resolve dependencies, create mapping files and make the bundles?
Both Typescript and Gulp are evolving very fast and I cannot find documentation for this use on their documentations (1, 2). I would appreciate feedback from experienced people also working on the latest versions of these technologies.
Moving comments to answer:
We have doing very similar exercise at my organization, towards the end of it.
We have used webpack for most of the stuff, though webpack feels little grunt'y and after gulp, I am not a big fan of grunt.
We have used webpack to convert ts to js, bunding, minification. We have not used it yet for html to js string or css in js.
regarding the di part, you will have to worry about only js to ts. ts to js is not an issue as it is taken care by angular's string based di. regarding ts to ts, you will need to defined needed interfaces. Those will help you in moving those js to ts in future. Better to start with core components with least dependencies.
EDIT
Just to answer the part regarding the advantages of having gulp: specifically in the migration scenarios is, the upgrade is not going to happen in one go, so whatever is moved to TS should be handled by tsc and remaining by gulp.
Also gulp is much larger than just ts to js, we are still using it to create deployment package, inject js into html, fixing boostrap font paths, converting small images to base64, etc etc....
tsc has one purpose: to transpile (compile) typescript files.
gulp, on the other hand, is a build tool, which means it can run various tasks including compiling typescript, sass, minification, concatenation etc.
You can look here for an example on how to incorporate typescript and browserify using gulp: https://www.typescriptlang.org/docs/handbook/gulp.html
Another approach, is not to use gulp at all, but rather use npm scripts, you can see a sample here: https://medium.freecodecamp.com/why-i-left-gulp-and-grunt-for-npm-scripts-3d6853dd22b8#.a7lwcmpaf
I believe the absolute simplest way to do this is to use Zwitterion. You can read this article for a quick introduction.
Zwitterion allows you to include TypeScript directly into the browser through normal script tags. All features of TypeScript are automatically available, because the code is transpiled server-side on a file-by-file basis as it is served to the client. Under the hood, it uses SystemJS to emulate the real ES module loader behavior that will be standard in all browsers. If you need this to work in production, you can create a static build with Zwitterion. All of this eschews bundling, so you'll have to decide on what your needs are for performance. Personally, I'm betting on performance not being that big of an issue with HTTP2, and I prefer the simplest of builds to the complication that webpack and all of its friends bring.
As you are moving forward with typescript, my recommendation would be to integrate any module bundler such as webpack (my favorite) Internally it will use ts loader to transpile the code. Also along with compile, you would be able to use ts lint for static code analysis (webpack would take care of it). Webpack also helps if you want to have multiple modules created. Try out yomen https://github.com/FountainJS/generator-fountain-webapp . Once scaffolded you can refer to generated gulp files. It would give you an idea about typescript integration.
The best way to do this without overengineering your gulp setup is to use the plain typescript compiler:
1. Install typescript locally(it won't conflict with your global tsc):
npm i typescript --save-dev
2. Add tsc as npm script(inside package.json).
"scripts": {
"tsc": "tsc"
}
3. Create proper tsconfig.json for your needs and put it in the same folder as package.json
https://www.typescriptlang.org/docs/handbook/tsconfig-json.html
4. Use tsc compiler directly from gulp
var child_process = require("child_process");
gulp.task("build", function(cb) {
var tsc = child_process.spawn("npm", ["-s", "run", "tsc"], {stdio: "inherit", cwd: __dirname});
tsc.on("close", function(code) {
console.log("Tsc finished with code", code);
cb();
});
});
Tip. Use https://www.npmjs.com/package/gulp-sequence and vote up :)

Resources