Angular2 and express node.d.ts conflict - node.js

I am trying to configure an angular2+express project. I understand the cause of the problem, but not the correct solution. Here are the relevant parts of my package.json dependencies:
"dependencies": {
"angular2": "2.0.0-beta.0",
"express": "^4.13.3",
"tsd": "^0.6.5",
"typescript": "^1.4.1",
<...lots of peer dependencies>
}
Node 5.2.0 is installed globally. When I run tsd install, I get ./typings/node.d.ts pulled in, for what the comments claim to be v0.12.0 API. But this conflicts with angular2/typings/node/node.d.ts (which also claims v0.12.0). The .d.ts files are different, for example:
./node_modules/angular2/typings/node/node.d.ts
---> declare var global: NodeJS.Global;
./typings/node/node.d.ts
---> declare var global: any;
The result is a mass of TS2300: Duplicate identifier errors. I can hack around this by manually deleting ./typings/node and editing ./typings/express/express.d.ts to have:
/// <reference path="../../node_modules/angular2/typings/node/node.d.ts" />
Now everything works, but obviously this is just plain 'wrong'. What is the standard way to pull in expres.d.ts so it plays nice with Angular 2?

Related

Are all packages from package.json included in React build?

I created a react app that both server and client shares the same package.json:
├───build
│ └───static
│ ├───css
│ ├───js
│ └───media
├───server (backend code)
├───src (client code)
├───package.json (shared)
My question is very simple, are all packages from package.json included in the final production React build?
For example, I use express for server. Is it included in the React build?
If so, is there any way to avoid it? Or did I choose a wrong architecture?
Edit:
Im using create-react-app, default mode
No* (in the common case).
The most popular react build tooling will use webpack (or other bundlers which do similar things). Webpack receives some "entry point filepaths", from those entry points he crawls for dependencies. Then webpack packs everything into a single output file (or a set of files, depending on the settings).
If you didn't import express from any of your frontend files, it won't go into the bundle.
Im not sure about combining the package.json for both your express and React app, I dont see an advantage to doing this since React uses webpack and combining the express server might mess up some of the default settings, I will share with you how I do it.
When you are in a development build you will have 2 separate apps running independently. Both the create-react-app and the node/express server will be running independently of each other and they will have their own separate package.json.
In production however you will run npm run build on your React app and it will be served as a static file from your express server. A built React app does not have a package.json
I have implemented both of these scenarios you can check it out here
Dev build:
https://github.com/iqbal125/react_hooks_fullstack_skeleton
Produiction Build:
https://github.com/iqbal125/react-prod9
Previously answered,
According to Webpack doc, Webpack generates a dependency graph starting from entry point which is usually index.js.
And also if you use something like create-react-app that uses webpack under the hood, it will generate a package json like this:
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.16.5",
"#testing-library/react": "^13.4.0",
"#testing-library/user-event": "^13.5.0",
"axios": "^1.3.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"build": "react-scripts build",
},
You can see there is no devDependencies! that means not all thing that you just put on the dependencies will be included in your final build.
Finally I've tested inside a new CRA my app:
pressed npm run build on the bare installed:
File sizes after gzip:
46.61 kB build\static\js\main.46f5c8f5.js
1.78 kB build\static\js\787.28cb0dcd.chunk.js
541 B build\static\css\main.073c9b0a.css
Installed axios via npm i axios, but never imported it.
output after running npm run build:
File sizes after gzip:
46.61 kB build\static\js\main.46f5c8f5.js
1.78 kB build\static\js\787.28cb0dcd.chunk.js
541 B build\static\css\main.073c9b0a.css
Nothin has been changed!
import axios from "axios", inside but never use it in the code:
import axios from "axios";
export default function App() {
return (
<div className="App">
</div>
);
}
This is the output:
[eslint]
src\App.js
Line 3:8: 'axios' is defined but never used no-unused-vars
File sizes after gzip:
46.61 kB build\static\js\main.46f5c8f5.js
1.78 kB build\static\js\787.28cb0dcd.chunk.js
541 B build\static\css\main.073c9b0a.css
Again nothing changed! but you can see eslint warning too!
Use one of it's functions e.g. get method only:
import axios from "axios";
export default function App() {
console.log(axios.get);
return (
<div className="App">
</div>
);
}
the output:
File sizes after gzip:
57.92 kB (+11.31 kB) build\static\js\main.4c83ea39.js
1.78 kB build\static\js\787.28cb0dcd.chunk.js
541 B build\static\css\main.073c9b0a.css
Conclusion:
If we don't use a package inside our app, it won't get into the final build.
Note:
Although extra packages won't affect production, don't forget to uninstall unused packages from time to time.
Running npm install still install every package defined in the package.json, no matter whether they are used or not. So having loads of unused packages will slow down deployment and affect your teammates (they need to run npm install as well!!.
Reference

Warnings when building backend Express/WS Node app with Webpack

I am getting some confusing warnings when building a backend Node server with Webpack. I want to use Webpack to build my backend primarily for two reasons:
Webpack creates a single executable file, which is easier to deploy
Webpack includes all of my app's dependencies, so I can deploy my app to any compatible Node environment without needing to install dependencies first
Here are the warnings I'm getting:
WARNING in ./~/ws/lib/BufferUtil.js
Module not found: Error: Can't resolve 'bufferutil' in .../node_modules/ws/lib
# ./~/ws/lib/BufferUtil.js 35:21-42
# ./~/ws/lib/Receiver.js
# ./~/ws/index.js
# ./src/main.js
WARNING in ./~/ws/lib/Validation.js
Module not found: Error: Can't resolve 'utf-8-validate' in .../node_modules/ws/lib
# ./~/ws/lib/Validation.js 10:22-47
# ./~/ws/lib/Receiver.js
# ./~/ws/index.js
# ./src/main.js
WARNING in ./~/express/lib/view.js
80:29-41 Critical dependency: the request of a dependency is an expression
For the Critical dependency warning, I've found a good example explaining the problem and some documentation on how to use the ContextReplacementPlugin, although it's still unclear to me how to apply it to this situation. It looks like the warning is being caused by line 80 in node_modules/express/lib/view.js:
opts.engines[this.ext] = require(mod).__express
It is clear to me that the dependency cannot be resolved at build time, so how can I use the ContextReplacementPlugin to fix this dependency?
As for the Module not found warnings in the ws package, it's unclear to me what's going on. It looks like those dependencies exist in my global node_modules, and maybe they're not being pulled in by Webpack. I've tried adding them to my project's devDependencies, but then I just get Critical dependency warnings for them instead.
My application still runs after being built, so I suppose I could technically ignore the warnings, but I figure that these are widely used Node packages and Webpack is a popular build tool, so there must be a reasonable solution available.
Here are my dependencies in my package.json:
"devDependencies": {
"#types/cassandra-driver": "^0.8.10",
"#types/express": "^4.0.35",
"#types/uuid": "^2.0.29",
"#types/ws": "0.0.40",
"nodemon": "^1.11.0",
"typescript": "^2.3.1",
"webpack": "^2.5.1"
},
"dependencies": {
"cassandra-driver": "^3.2.1",
"express": "^4.15.2",
"uuid": "^3.0.1",
"ws": "^2.3.1"
}
And here's my webpack.config.js:
const path = require('path');
module.exports = {
entry: './src/main.js',
output: {
path: path.join(__dirname, 'dist'),
filename: 'main.js'
},
target: 'node',
node: {
__dirname: false,
__filename: false
}
};
I like keeping things minimal if possible. Thanks for reading.
The short answer
webpack can work with node, but it cannot extract follow require() statements. Modifications have to be made to ignore require() in order for it to work.
The long answer
It is actually possible to pull some files into a master file and run it in some instances.
One instance is if all the modules required are written in typescript and the modules are written in a away that the typescript plugin can parse the module in.
Another instance would be if you are using es6 babel plugins and using es6 style imports.
Even in the above scenarios the blunder may choose not to pull in certain files
The ultimate answer
It really should not matter too much about trying to perform the long answer because modules are stored in memory at boot and then referenced later from the cache. See the article below for more information.
http://fredkschott.com/post/2014/06/require-and-the-module-system/

webpack import error with node-postgres ('pg'.Client)

Trying to bundle the following file with Webpack fails with
ERROR in ./~/pg/lib/native/index.js Module not found: Error: Cannot
resolve module 'pg-native' in
.../node_modules/pg/lib/native
# ./~/pg/lib/native/index.js 9:13-33
I tried several ignore statements in the .babelrc but didnt get it running...
The test-file i want to bundle: handler.js
const Client = require('pg').Client;
console.log("done");
webpack.config.js
module.exports = {
entry: './handler.js',
target: 'node',
module: {
loaders: [{
test: /\.js$/,
loaders: ['babel'],
include: __dirname,
exclude: /node_modules/,
}]
}
};
.babelrc
{
"plugins": ["transform-runtime"],
"presets": ["es2015", "stage-1"]
}
package.json
"dependencies": {
"postgraphql": "^2.4.0",
"babel-runtime": "6.11.6"
},
"devDependencies": {
"babel-core": "^6.13.2",
"babel-loader": "^6.2.4",
"babel-plugin-transform-runtime": "^6.12.0",
"babel-preset-es2015": "^6.13.2",
"babel-preset-stage-0": "^6.5.0",
"babel-polyfill": "6.13.0",
"serverless-webpack": "^1.0.0-rc.3",
"webpack": "^1.13.1"
}
Somewhat related github-issues:
https://github.com/brianc/node-postgres/issues/1187
https://github.com/serverless/serverless-runtime-babel/issues/8
This is indeed an old thread, but one that helped me nonetheless.
The solution provided by Steve Schafer 1 is good, but not the simplest.
Instead, the one provided by Marco Lüthy 2 in the linked issue is probably the easiest to set up because it is pure configuration, without even the need for a dummy file to be created.
It consists of modifying your Webpack config plugins array as follows:
const webpack = require('webpack');
const webpackConfig = {
...
resolve: { ... },
plugins: [
new webpack.IgnorePlugin(/^pg-native$/)
// Or, for WebPack 4+:
new webpack.IgnorePlugin({ resourceRegExp: /^pg-native$/ })
],
output: { ... },
...
}
Updated to include a change suggested in the comments.
This is an old thread but the problem still exists, so for anyone experiencing it, there is a workaround. The problem is an interaction between the way that node-postgres is written and how babel rewrites the code, which forces pg-native to be loaded even when you don't explicitly import/require it.
The simplest workaround is to add a couple of aliases to your webpack.config.js to cause it to link in a dummy do-nothing file instead:
{
...
resolve: {
alias: {
...
'pg-native': path-to-dummy-js-file,
'dns': path-to-dummy-js-file
}
}
...
}
where the dummy file contains a single line:
export default null
See https://github.com/brianc/node-postgres/issues/838 for further discussion and alternative workarounds.
I know that this is an old topic but I'm compelled to share how I solved it. It was maddening to deal with.
So, here is the readers digest version as based on the recollection from the last brain cell that I have.
Error:
Webpack Compilation Error ./node_modules/pg/lib/native/client.js Module not found: Error: Can't resolve 'pg-native'
The error above was thrown when attempting to run a Cypress test that required the npm package 'pg'.
Attempting to install the pg-native package was not successful and resulted in another error; namely ->
Call to 'pg_config --libdir' returned exit status 1 while in binding.gyp. while trying to load binding.gyp
I found that executing pg_config --libdir in the VSCode cmd prompt resulted in that command failing.
However, I knew that it should work since running that command from the system command prompt resulted in this -> C:/PROGRA~1/POSTGR~1/9.3/lib
That is the path that contains a required dll.
So, instead of running npm install from the VSCode command prompt, I ran it from the command prompt as launched from windows.
The result...success!!! pg-native was installed successfully.
After, the Cypress test was able to run as well.
Errors in now way helped me to arrive at this solution. It was more just checking that things were installed that were required, etc.
You may have pg-native globally installed locally. Hence the packet manager does not include the pg-native in the lock file. That was a issue i experienced where it did run fine locally but every time i build in the cloud webpack complained about pg-native missing. I solved it by removing the lockfile in the files pushed to the cloud (In this case seed.run).

Using two different versions of the same node dependency

Is there a way to include two versions of the same dependency in nodejs package.json?
For testing purposes, I need to use two versions of socket.io (one to expose a socket in the latest version and one to simulate a dependency server using an old release).
{
"dependencies": {
"socket.io": "~0.9.0",
"socket.io": "~1.2.0"
}
}
Maybe not the best solution, but you can first fork socket.io 0.9 on github:
https://github.com/Automattic/socket.io/tree/0.9
To create https://github.com/youaccount/socket.io/tree/0.9
Then use this:
"dependencies": {
"oldsocket.io": "git+ssh://git#github.youaccount/socket.io.git#0.9",
"socket.io": "~1.2.0"
}
Edit the package.json and rename the name attribute to oldsocket.io
And you can now require socket.io or oldsocket.io

Dustjs custom filters stopped working

For some reason my dustjs custom filters have just stopped working on the production server, even though they work fine on my local machine. Anyone have any thoughts as to why this might be happening? I am using dustjs-linkedin v. 2.3.5.
What my filters look like (located in my main server.js file):
dust.filters.uppercase = function (value) {
return String(value).toUpperCase();
};
dust.filters.ucwords = function (value) {
return String(value).replace(/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g, function($1) {
return $1.toUpperCase();
});
};
dust.filters.money = function (value) {
return parseFloat(value).toFixed(2);
};
UPDATE: I really need this fixed, and am at a loss as to why this would work locally, but not on my server (this used to work just fine). Unfortunately, I didn't notice when it stopped working and have made MANY updates. Any ideas would be GREATLY appreciated.
Here are the app dependencies from my package.json:
"dependencies": {
"express": "3.4.8",
"socket.io": "0.9.16",
"dustjs-linkedin": "2.3.x",
"dustjs-helpers": "1.2.0",
"consolidate": "0.10.0",
"mongoose": "3.8.x",
"node-uuid": "1.4.1",
"express-form": "0.10.1",
"bcrypt-nodejs": "0.0.3",
"subdomain": "0.1.0",
"gm": "1.14.x",
"connect-mongo": "0.4.1",
"nodemailer": "0.6.5"
}
ANOTHER UPDATE: I have added a console.log('money'); to the money filter and it logs every time it is run locally just fine, but never logs anything to the console on the production end. This leads me to believe that the custom filters are not being added on the production server for some reason.
YET ANOTHER UPDATE: I literally added the filters to the dust source code, and they still wont run on the production server, but work fine locally. Could using NODE_ENV somehow be causing something to mess up in dust?
Inspect the node_modules directory tree. My guess is you will find two instances of dustjs-linkedin. Your filters will be in one but you are using the other one. Something else is dragging in the other copy based on a different version.
I think it happened because you have updated some packages to more recent versions.
I have similiar thing with nodemailer package upgrade from 0.7.1 to 1.0.2 versions
Can you prodive the dependecies hash of package.json file?

Resources