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
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)
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.
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.
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 :)