Do devDependencies affect bundle size? - javascript

I looked hard, and couldn't find a straight answer to this question.
Do the packages I add as devDependencies actually end up in the production bundle JS file and thus affect its size? Or is it only the dependencies that go into the bundle?

No it will not affect your bundle size because those package are only using in development mode. Let's take an example package like typescript
devDependencies: {
"typescript": "~3.2.5"
}
So I only need to have typescript compier, linting just in dev mode. And I'm not actually import typescript in my project because it's only use for dev mode. So if you are using webpack and you wont import typescript anywhere then in your project webpack will you tree shaking to eliminate code that don't need for production build so the bundle will not affect.

The answer is not that easy as might look. Here is clarification: https://github.com/webpack/webpack/issues/520#issuecomment-174011824
And adding relevant snippet here:
A browser app built by webpack has no runtime node dependencies, and thus all frontend dependencies should be listed as devDependencies. The dependencies vs devDependencies naming convention stems historically from node being a server side package manager, which was abused into a frontend package manager, and this is why the fields have names that are counter-intutive when applied to frontend dev, and is why every project ever is getting this wrong. It is as far as I can tell harmless to list frontend dependencies under dependencies, but it is wrong.
I hope this answers your question.

Related

Workflow to use a sub-module typescript written module into a non-typescript module?

I'm having a private typescript module that is a dependency of another major project. This dependency is achieved by having the typescript repository as sub-module and installed using npm to the local sub-folder. The typescript module can compile into JavaScript on its dist folder and by doing so the major module that consumes it can make use of it without issues. But here is my problem, the dist folder isn't committed to the typescript repository.
What should be the workflow to follow in order to consume this typescript module from a JavaScript-only major project? The best I can think at this moment is to instruct someone, or something, to run the $ tsc command before using the major project but it's "annoying" since it isn't a transparent step. If this is a weird approach, what would be a more ideal approach? Thanks everyone.
You have a couple of options.
Assuming you're not planning to have a private npm registry using e.g. Verdaccio you can simply commit the dist folder. This is definitely the simplest option and it's not completely unheard of, I'd probably go with that option.
This solution is actually quite unusual, but it's pretty clever and it works. You could add a postinstall script in package.json of your TypeScript package that would run tsc after installing the package. The downside is that you'd have to add typescript as your dependency, which is not ideal (it should generally be a dev dependency, in which case it wouldn't be installed in the project using the package), but for some it might not be a big deal at all.
Instead of installing the package, you could use npm link and then have a script in your main project that would compile it. You'd have to run it every time something changes in that package, though. You could also append it to your npm start script, so it runs before it, e.g. "start": "npm compile-package && webpack" (assuming your current start script is "start": "webpack"). It doesn't scale very well though.
If your Javascript project uses Babel (and I'd assume so considering you said it's a "major" project) you could change its config so it transpiles Typescript for you using #babel/plugin-transform-typescript, however it can be a bit complicated, IIRC e.g. projects created with create-react-app by default don't recompile the code from node_modules.
There are probably more solutions, but I'd probably go with 1 or 2.

Publish NPM package with only non-bundled dependencies

Lets say we're developing a small javascript library L.
The code is in ES6. To use some utility function, like debounce, we install lodash as a dependency.
At build the webpack transpiles the code, bundling the tree shaked lodash code, and we end up with a nice little javascript file we want to publish and share as a npm package.
Now, the package.json file lists lodash as a dependency. But that is only true at build time, it is not really needed in production.
What's the proper way to handle this kind of situation?
Does it make sense to consider lodash a devDependency? As such, only webpack's externals would be "real" dependencies?
Or should we somehow tamper the package.json file before publishing it?
Do you know any real examples of projects handling this question?
Webpack "merges" the code of the project with that of the used code of the non-external dependencies into some bundle.js file. This file is then published to NPM, along with a package.json file, which lists all of the dependencies, independently of these being external or embedded.
All of the code of packages referenced in dependencies (or optionalDependencies, or peerDependencies) is expected to be "production" code.
While code in devDependencies is expected to be used only at "development" time, and is thus "development" code. Under this principle, I believe that it would be incorrect to declare non-external dependencies as development dependencies.
However, if all dependencies, embedded or external, are declared equally in the published package.json file, there is no way for a runtime environment to know which are the real dependencies that need to be made available to the package — the ones that the package will import at runtime and which better be available.
For the Node.js environment, bundles and Webpack are not normally used, so this never came to be an issue — all dependencies are always installed (never merged/bundled).
However, if you use the package.json file to drive some web-packages runtime environment, the way that dependencies are currently included in published package.json is not suitable.
You might want to take a look at Pika Web's devDependencies package.json property, which aims to solve a comparable problem (even though their mojo is "a future without Webpack"). They also introduce the concept of publishing a different package.json file than that which is checked-in (tampering the package.json before publishing, as you say).
Interestingly, it looks like a related tool, Pika Pack, caught the attention of NPM folks and is being considered to become part of NPM. So, maybe, NPM has become aware of the specific package format needs of web projects' workflows.

Converting React component to a single js file to integrate it with a blank html

A react component is developed using JSX. How to convert it to browser understandable JS code and minified to 1 js file so that it can be included as a single script tag in html ?Am very new to Js world and heard of babel and webpack.not sure how to use it and covert it to the same.
I got things generated after react-scripts build.but images are not serving if i deploy them in weblogic as static
For converting jsx into browser runnable js code, you would have to use babel. You can use babel-preset-react for this(via configuring .babelrc).
Babel Preset for React
Complete steps:
Run npm install babel babel-cli babel-preset-react
Define .babelrc at project root level, with following content
{
"presets": ["react"],
}
Run babel {jsxFile}.jsx --out {jsFile}.js
Am very new to Js world and heard of babel and webpack not sure how to use it
The statement above tells me that setting up npm build pipelines might best be avoided.
So assuming you have the component in jsx and you would like to use the javascript version, you will need to "convert" it. If it is a component that doesn't change quite a lot, you can take a look at the online babel.io repl (this is recommended by the official documentation site as well).
However, this approach can be tedious if your component changes frequently. I can highly recommend create-react-app for development. It is an opinionated toolkit which hides away webpack and babel configuration, but at the same time, their opinions are well documented and work for many general use cases.
Edit
From your comments, it seems you are already using react-scripts, then the most probably problem I see is that you perhaps forgot to specify the homepage property in your package.json (see relevant documentation) By default CRA assumes your static assets are hosted at server root, I assume you are not deploying your WAR in ROOT context, so you need to provide a static location.
I have a similar setup, where I need to package my site built with react inside a war file, I have the following setup:
in package.json
"homepage": "/<webapp_context>/build"
Then with gradle, I copy the build folder in its entirety to the WAR file (same level as WEB-INF).
This instructs react-scripts to put relative paths in all the static assets it publishes (such as CSS, js and images) and the imports then work.

Webpack HMR: Does not watch changes to external packages in /node_modules

I have a project on React + Webpack 2. Since recently, there was a need to divide the project into modules. I decided to use Monorepo with Lerna. But I have caused a lot of problems. One of the main problem is that the changes that I make to the linked package do not cause automatic assembly.
I think that I did not take something into account. Tell me what could be the problem?
My config:
https://github.com/react-boilerplate/react-boilerplate/tree/master/internals/webpack

When it comes to using react with yeoman

There are a ton of packages out there that have this all bundled up but I dont like the way they set up the projects and such so I was reading the Reactjs docs on installing with npm and my confusion is:
After installing it using npm install react or adding react to
package.json
Do I add this to the "devDependencies": {} or ...
for the require statement to work, do I need to include requirejs?
Can I just do grunt serv to start everything and auto compile the jsx or do I need to do this? (it seems like that might be answered for me ..... but how can I get it to auto compile the jsx when I run grunt serv)
I ask these questions and state I don't like the existing yo ... commands for this because they don't play nicely with bacbone.js So I was going to set this up my self. if there are any repos out there for yeoman that do this for me please point me to them.
dependencies vs devDependencies: for npm package.json, devDependencies are mainly used for the tooling around working on the project itself: testing tool chain and project building modules, for example. Things you'd often see in there: Mocha, Grunt, etc. So mostly for repo contributors and alike. As a consumer of React, you'd put it in dependencies, which are for modules that your code actually needs in order to work.
require isn't for requirejs. The naming clash is unfortunate. require() is part of CommonJS. Node uses CommonJS. Browserify too. Here, it's assuming that you're using Browserify, or maybe doing server-side React with Node.
I'm not sure what you've set up to use with grunt serve. There's nothing magical that makes it work by default. You do need to do what the link said. The --watch option will look for changes to your files and auto compile the jsx to js.
Hope that helps!

Categories