why react should usually be a prod dependency and not dev-dependency - node.js

Sorry if I'm missing some obvious thing, but I can't seem to understand why react (or react-dom) should be a dependency and not dev-dependency on most projects..
Usually the src is written in es6 and stored in /src or /client for example, and when someone want to build the project for prod he will create /build or /dist where the finalize bundle.js will seat (using webpack and such). from there (at prod) it simply a web server which serve regular js (the bundle) and html file.
Do I miss somthing?
I dont understand why will I want react on the prod (unless going for SSR of course)..
Thank you very much!

dependencies are required to run, devDependencies only to develop, e.g.: unit tests, Coffeescript to Javascript transpilation, minification, ...
React is a dependency because it is included in the final build.
In case of a React App, all your JSX is converted to a syntax similar to React.createElement and hence you would require your App to have React during run time as well. Similary methods like setState and lifecyle functions are all executed during run-time.
As a matter of fact react is a library that has exposed some methods and APIs to access and manipulate DOM.
Consider this similar to jquery or express where you add it in the production build because they are being used during run time.
When creating a react app, things like babel, webpack etc which are only used to create a bundle would be dev-dependencies as once the packaged bundle is generated it need not be generated during run time of application

I had the same question and found this article that explains it well.
To summarize, it shouldn't matter where you put the react dependencies since Webpack will bundle them into a self-contained file and the code will run fine in either case. However, separating development and production dependencies allows for a better communication to other developers for the purpose of these dependencies.

A dependency is something that is imported in the src/ or client/ module like you mentioned. The code that you run depends on it and hence is required in the production bundle.
If it were something like Babel it could be a devDependency because:
It is not imported in source code.
It is a transpiler and works on code in compile time
But that is not the case with React. Functions like setState or lifecycle hooks are being executed in run time, meaning the library has to be present during run time.
React could very well be listed as a peer dependency is some of the popuar libraries. This is because we assume that all projects that are going to use this library are going to have React installed. Like consider the case of react-bootstrap. It can only be run in react projects, so we include react as peer dependency reducing the overhead of installing it.
If you need a framework that would disappear in compile time, take a look at Svelte.

Related

Project too large

I'm just starting to learn Angular, I installed in my Ubuntu Linux:
Angular CLI: 7.1.4. and
Node: 10.14.2.
My question is, why one project is too large? I mean a simple "helloworld" is 334MB, I don't know why, Is it possible resize it? or delete any folder that is unnecessary? Or Is there something wrong with my installation? (how can I detect that?)
The bigger folder is node_modules, and when I create my projects, generates a lot of folders.
I was reading about "angular lazy loading", but I'm new.. It is not totally clear for me.
this is the folder spaces:
Please... I hope somebody can help me...
best regards
You might be using big bundles which are not needed, so you can break them up:
https://medium.com/#julienetienne/javascript-bundles-are-too-big-break-up-the-libraries-3be87d5ef487
In modern JavaScript, projects require modules that themselves require modules that require modules... resulting in node_modules directory with hundreds of dependencies. A 100Kb library might be included because someone needed one function from it. JavaScript is not compiled, so all that source tends to be rather big. This is an unfortunate, but unavoidable truth; your Angular project directories will be big, and there's nothing you can do about it. It is perfectly normal.
The good part: modern JavaScript deployment typically includes packing up those libraries with Webpack or Parcel or similar code bundlers. Most of them implement "tree shaking", which analyses the code to find only the functions that are potentially utilised starting from the entry point, and only bundle those, ignoring the rest. This means that 100Kb library whose one function is used is transformed into just that one function in the final distribution bundle.
Not all of the bundlers are equally good at it at this point. For example, Webpack cannot tree-shake the CommonJS modules, only ES6 ones.
You can remove node_modules folder when you are not going to use the app.
And, when you need work on the application, you can re-generate node_modules using the command: npm install
Those are just node-modules, they are needed for building the project, but not necessarily everything inside of them will be deployed to production. As Amadan said, there is a process of tree-shaking (filtering only used modules) and also in production you use the minified version of the same JS code (where for example whitespace is missing and variable-names are shortened), among other optimizations. A production-optimized Angular project should not be more than a 100KB for a hello-world application.
In the provided image I see packages like
selenium-webdriver
protractor
Those belong to dev-dependencies (see your package.json file) because they are used for testing. When building for production, no code from dev-dependencies should be included. The typescript package (which is nr.2 in size in your screenshot) will also not be present in production because types like string are only used for writing Typescript code, but the browser receives Javascript, which it is compiled to.

Building monorepo babel-transpiled node JS application with dependencies

I am working on a project that is hosted as a monorepo. For simplification purposes let's say that inside there are three self-explanatory packages: server, a webapp client and library. The directory structure would be something like the following:
the-project
packages
server
src
webapp
src
library
src
All packages employ flow type notation, use a few >ES5 features and, for this reason, go through babel transpilation. The key difference is that transpilation of the webapp package is done via webpack, whereas server employs a gulp task that triggers script transpilation through the gulp-babel package. library is transpiled automatically when web is built.
Now, the problem I have is that for server to build, babel requires library to be built first and its package.json to specify its (built) main JS source file so its transpiled artifacts can be included. As you can imagine, this would quickly become problematic if the project were to contain multiple libraries that are actively being developed (which it does), as all would require building, including any dependent packages (like server in this simple case).
As an attempt to overcome this annoyance, I initially thought of using webpack to build the server, which would take care of including whatever dependencies it requires into a bundle, but I ran into issues as apparently webpack is not meant to be used on node JS applications.
What strategies are available for building a node JS application requiring Babel transpilation, such that the application's source files as well as any dependencies are built transparently and contained in a single output directory?
Annex A
Simplified gulp task for transpilation of scripts, as employed by server.
return gulp
.src([`src/**/*.js`], { allowEmpty: true })
.pipe(babel({ sourceMap: true }))
.pipe(gulp.dest('dist'));
As can be seen above, only server's own source files are included in the task. If src were to be changed to also include library, the task would emit the dependencies' artifacts in server's own output directory and any require('library') statements within would attempt to locate the built artifacts in packages/library and not packages/server/dist, thus resulting in import failures.
First of all, I am not sure what your server is doing. If it is doing a database connection or some calculations then I would not recommend it to be built by webpack. Whereas If your server is just doing Server-Side Rendering and making some API calls to other servers then I would recommend it to be bundled using webpack.
A lot of projects follow this philosophy. For example, you can take a look at something similar, I have done in one of my personal projects [Blubus]. Specifically, you might be interested in webpack-server-config. And also you can take a look at how big projects like spectrum does it.

Best practices to develop VueJS app with Webpack, SASS, NPM ...?

I am writing application by using Python/Flask as the API back-end, and want to separate the front-end (browser-based) as an individual project (VueJS). I've read about Webpack, but I can't find any best practice to start, such as: can we use NPM to manage dependencies, use webpack for front-end not using an Node app as an entry ...
Thanks alot
WebPack isn't a framework.
It's something that a task runner.
Exemple: You use SASS, you want something that compile all your sass file in CSS file. You create a task and webpack have a task now. And you can ask him to automaticaly compile the file when change.
Maybe what you want it's more have two project:
One who handle the data an may available with an api
One who is the web ui for the user who get the data and format it in a beautifull UI
Webpack won't be your solution. Continue with your VueJS and look at VueX for your data handling browser side.

The best way to actively develop an NPM package that's consumed by another app running locally

I'm currently working on a React application that's consuming a React library we also develop.
Currently, the process is to copy over the dist folder of the library over to the node_modules folder of the application.
To resolve the tedious nature of this, I thought the solution would be simple: to npm link the package in our application, and have the JSX/React components run through the application's babel-loader. That way, we'd also get webpack's dev server to watch for changes in the library and refresh automatically.
The problem with this is that the library's babel settings are different from those of the consuming application. For instance, root imports in the library (e.g. import ~/some-module) are supposed to resolve from the root folder of the library, but instead, they resolve to the root folder of the application, resulting in errors, because the only babel configuration it uses is the .babelrc from the application.
I tried adding separate webpack config rules to make exceptions for the library, but now it feels kind of hacky. In addition to that, the webpack dev server runs incredibly slow to boot up, presumably because it's running a babel transformation on the library too.
Is there an easier way to do this? Like telling webpack that "for this library in node_modules, use its own configuration file, and respect all of its own babel settings and relative imports?"

Babel usage in web app - node, react, gulp, browserify

I would like to start using advanced JS features in an pre-existing app with a NodeJS serverside, React using the Fluxible architecture, Gulp task runner and Broserify/CommonJS front end modules.
Anybody who has been down that path or a similar path before and wants to share some insight I would much appreciate it.
babel-node compiles on-the-fly. You can use the API (babel-core) to pre-compile and then run the compiled output in node. There's also a gulp-babel plugin. At the expense of extra processing overhead at build time you could hijack browserify or use module-deps to figure out the dependency graph for you, if relevant. There's a notion of adding a feature to Babel to generate a dependency graph, but it's not available currently.

Resources