How to bundle NodeJs Application? - node.js

Consider I have been done with my NodeJs with Express and MongoDB Application. I can bundle up my application to deliver the same to client but in that case client have to install all required npm modules and change mongoDB connection url. So to counter this issue:
Is there any other way to bundle my application so client do not need to install any npm modules to run application? If yes, then how client can connect to his mongodb?

pkg by Vercel works really well for me. It bundles everything into a single executable that runs out of a terminal. This makes it really easy to distribute.
To connect to a Mongo instance, you would have to have some kind of configuration file that the user edits. I recommend putting into the user data folder (Application Support on Mac and AppData on Windows), but you could have it sit right next to the packaged executable.

You can use good old webpack by setting it's target. here is an example webpack.config.js file for node:
import webpack from 'webpack';
export default {
entry: "./server.js",
output: {
// output bundle will be in `dist/buit.js`
filename: `built.js`,
},
target: 'node',
mode: 'production',
plugins: [
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1
})
],
};

Related

Gatsby Source Drupal not fetching data when trying to deploy to netlify/heroku

I have a site running Gatsby and Gatsby-Source-Drupal7, it is a plugin that uses Graphql to make an axios get request to https://stagingsupply.htm-mbs.com/restws_resource.json and uses the json data to query. I am able to run it just fine on my computer by going to localhost:8000 and it creates over 200k nodes, but when I try to deploy on any cloud service provider like Gatsby Cloud or Netlify it doesn't fetch any nodes or data at all from the site.
Warning from console
Starting to fetch data from Drupal
warn The gatsby-source-drupal7 plugin has generated no Gatsby nodes. Do you need
it?
Code
code from gatsby config
module.exports = {
siteMetadata: {
title: `new`,
siteUrl: `https://www.yourdomain.tld`,
},
plugins: [
{
resolve: `gatsby-source-drupal7`,
options: {
baseUrl: `https://stagingsupply.htm-mbs.com/`,
apiBase: `restws_resource.json`, // optional, defaults to `restws_resource.json`
},
},
]
}
gatsby-config.js from node_modules/gatsby-source-drupal7
const createNode = actions.createNode; // Default apiBase to `jsonapi`
apiBase = apiBase || `restws_resource.json`; // Fetch articles.
// console.time(`fetch Drupal data`)
console.log(`Starting to fetch data from Drupal`);
const data = yield axios.get(`${baseUrl}/${apiBase}`, {
auth: basicAuth
});
const allData = yield Promise.all(_.map(data.data.list,
Link to repo that works on local computer https://github.com/nicholastorr/gatsby-d7
any and all help will be appreciated
As you pointed out, you've played around with the Node versions using NODE_ENV and engines workarounds. My guess also relies on a mismatching Node version between environments but as Netlify docs suggests, there are only two ways of customizing Node versions to manage dependencies.
Set a NODE_VERSION environment variable.
Add a .node-version or .nvmrc file to the site’s base directory in your repository. This will also tell any other developer using the
repository which version of Node.js it depends on.
Without seeing your Netlify build command (to see the NODE_VERSION) there's no .node-version nor .nvmrc in your repository. I'd try creating it at the root of the project with the v14.17.1 in it and trying a fresh install.
In addition, double-check other server-related conflicts like IP-blocking, etc.
Error was nothing Gatsby or Node related, my site was block the IP of the server :>

NodeJs Debugging Client-Side Visual Studio Code with FuseJs

I have two application which has developed with Typescript. They are server-side and client-side application. I used NodeJs for them. On client-side also used fuseJs for hot-reload feature. But I have a problem I can't debug the client-side application. I'm always writing to console and there is so much "console.log() lines".
I can debug my server-side. But I can't debug client-side.
Here is my fusejs configuration:
const { FuseBox, WebIndexPlugin, CSSPlugin, CSSResourcePlugin } = require("fuse-box");
const { src } = require("fuse-box/sparky");
const fuse = FuseBox.init({
tsConfig: "tsconfig.json",
homeDir: "src",
target: "browser#es6",
output: "dist/$name.js",
plugins: [
WebIndexPlugin({template:'src/dashboard.html'}),
CSSPlugin()],
});
fuse.dev({port:8080});
fuse
.bundle("app")
.instructions(" > main.ts")
.hmr()
.watch();
fuse.run();
I was run my client-side app like: node fuse.js but I read this docs: https://nodejs.org/api/debugger.html then I added "debugger" line to my code and I run it: node inspect fuse.js
But I can't still debugging it. Somebody suggested chrome debug extension but I don't want change my any config or don't want to be reason for it. Is there any other way before try this extension? Can anybody help me?

office-js + outlook-web-addins + Webpack + Production

I am totally new to NodeJS, Webpack and specially to Outlook Addin. So, I created my Outlook Addin using basic tutorials from https://learn.microsoft.com/en-us/outlook/add-ins/addin-tutorial, all went well.
However, when it came to deployment on Production, I struggled a lot. I put all my code up on Production (Ubuntu instance). First tested a simple NodeJS "hello World" app on Port:8080 and it worked just fine. Then I tried to start my Outlook Addin, just like I was doing locally, it started on port 3000, but I needed to run it on 8080 and in the background. So, I used "PM2", and here comes the "WALL".
pm2 start src/index.js doesn't work for me, as the inside Office.onReady or any other reference to Office does not work, throws undefined Office error.
I tried pm2 run-script build, (after modifications in package.json and webpack.prod.js files)
However, I am still getting the same error when try to run pm2 start dist/app.bundle.js
So, please guide me which file should I reference to when using pm2 start {filename/path}?
Here are some configurations that I am using,
webpack.common.js
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
polyfill: 'babel-polyfill',
app: './src/index.js',
'function-file': './function-file/function-file.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.html$/,
exclude: /node_modules/,
use: 'html-loader'
},
{
test: /\.(png|jpg|jpeg|gif)$/,
use: 'file-loader'
}
]
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Production'
}),
new HtmlWebpackPlugin({
template: './index.html',
chunks: ['polyfill', 'app']
}),
new HtmlWebpackPlugin({
template: './function-file/function-file.html',
filename: 'function-file/function-file.html',
chunks: ['function-file']
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
webpack.prod.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
devtool: 'source-map'
});
Contents of an Add-in
The files that are produced from your project when building should be at least some JavaScript, then perhaps HTML and some CSS, depending on what kind of add-in you're building. The most common is probably building an add-in with a task pane - which is basically a web page. In any case, the built files is not a Node.js web server.
Hosting your Add-in
Making your add-in available inside Outlook or Office requires that you host your files somewhere. It can be done with any web server - a simple python web server, Apache, Node.js HTTP server, or anything similar. It can be done on either localhost or in some other hosting service. The add-in tutorial shows you how to run a Webpack development server to host the files on https://localhost:3000 while you are coding (npm run start).
In your manifest.xml file you'll notice that you specify the address where your files are hosted. In my development setup, for an add-in with a task pane, I've specified that the files are hosted on localhost, like this:
<FormSettings>
<Form xsi:type="ItemRead">
<DesktopSettings>
<SourceLocation DefaultValue="https://localhost:3000/index.html"/>
<RequestedHeight>250</RequestedHeight>
</DesktopSettings>
</Form>
</FormSettings>
Production
However, when running your app in production, the tutorial says that you should do npm run build. Those files that are produced, need to be hosted somewhere. I've hosted my add-in on Amazon S3, which is another way of hosting files.
To simulate it on localhost, follow these steps.
In the same folder as your project (where the dist/ folder is located):
Run npm install http-server -g
Run http-server dist/
Tools
To clarify what the tools are used for:
Webpack is what puts your app together, from your source code to a bundled version which can be run in a browser context. Webpack development server can be used to host files on localhost during development
Node.js HTTP server can also be used to host files on your localhost
pm2 is a process manager for Node.js. You can use it for hosting a Node.js server in production
#shahroon and I working on the issue together. We're still not able to get things to work and have now paid for a support with Microsoft. Sadly and very frustratingly Microsoft hasn't even acknowledge our support ticket and it's been 3 days.

Module not found : 'child process'

I'm developing a ReactJS app with Babel and Webpack. I am using the create-react-app facebook script so it handles the Webpack´s configuration. My problem is that I created a js file and add:
var childProcess = require('child_process');
But when I want to compile the new version i get the following error :
Module not found: 'child_process'.
I don't know what to do with this . I have read that adding custom configurations to the webpack.config.js may be the solution but i am using create react app so I don't have the Webpack configuration. I tried running npm run eject and create my own webpack.config.js but it doesn't work.
I hope somebody could help me.
You need to configure the correct target inside the webpack configuration: https://webpack.github.io/docs/configuration.html#target
module.exports = {
entry: './path/to/my/entry/file.js',
...
target: 'node',// we can use node.js modules after adding this configuration
};

How to not bundle node_modules, but use them normally in node.js?

Architecture
I would like to share code between client and server side. I have defined aliases in the webpack config:
resolve: {
// Absolute paths: https://github.com/webpack/webpack/issues/109
alias: {
server : absPath('/src/server/'),
app : absPath('/src/app/'),
client : absPath('/src/client/'),
}
},
Problem
Now on the server side I need to include webpack in order to recognize the correct paths when I require a file. For example
require('app/somefile.js')
will fail in pure node.js because can't find the app folder.
What I need (read the What I need updated section)
I need to be able to use the webpack aliases. I was thinking about making a bundle of all the server part without any file from node_modules. In this way when the server starts it will use node_modules from the node_modules folder instead of a minified js file (Why? 1st: it doesn't work. 2nd: is bad, because node_modules are compiled based on platform. So I don't want my win files to go on a unix server).
Output:
Compiled server.js file without any node_modules included.
Let the server.js to use node_modules;
What I need updated
As I've noticed in https://github.com/webpack/webpack/issues/135 making a bundled server.js will mess up with all the io operation file paths.
A better idea would be to leave node.js server files as they are, but replace the require method provided with a custom webpack require which takes in account configurations such as aliases (others?)... Can be done how require.js has done to run on node.js server.
What I've tried
By adding this plugin in webpack
new webpack.optimize.CommonsChunkPlugin(/* chunkName= */"ignore", /* filename= */"server.bundle.js")
Entries:
entry: {
client: "./src/client/index.js",
server: "./src/server/index.js",
ignore: ['the_only_node_module'] // But I need to do that for every node_module
},
It will create a file server.js which only contains my server code. Then creates a server.bundle.js which is not used. But the problem is that webpack includes the webpackJsonp function in the server.bundle.js file. Therefore both the client and server will not work.
It should be a way to just disable node_modules on one entry.
What I've tried # 2
I've managed to exclude the path, but requires doesn't work because are already minified. So the source looks like require(3) instead of require('my-module'). Each require string has been converted to an integer so it doesn't work.
In order to work I also need to patch the require function that webpack exports to add the node.js native require function (this is easy manually, but should be done automatically).
What I've tried # 3
In the webpack configuration:
{target: "node"}
This only adds an exports variable (not sure about what else it does because I've diffed the output).
What I've tried # 4 (almost there)
Using
require.ensure('my_module')
and then replacing all occurrences of r(2).ensure with require. I don't know if the r(2) part is always the same and because of this might not be automated.
Solved
Thanks to ColCh for enlighten me on how to do here.
require = require('enhanced-require')(module, require('../../webpack.config'));
By changing the require method in node.js it will make node.js to pass all requires trough the webpack require function which allow us to use aliases and other gifts! Thanks ColCh!
Related
https://www.bountysource.com/issues/1660629-what-s-the-right-way-to-use-webpack-specific-functionality-in-node-js
https://github.com/webpack/webpack/issues/135
http://webpack.github.io/docs/configuration.html#target
https://github.com/webpack/webpack/issues/458
How to simultaneously create both 'web' and 'node' versions of a bundle with Webpack?
http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/
Thanks
Thanks to ColCh for enlighten me on how to do here.
require = require('enhanced-require')(module, require('../../webpack.config'));
By changing the require method in node.js it will make node.js to pass all requires trough the webpack require function which allow us to use aliases and other gifts! Thanks ColCh!
My solution was:
{
// make sure that webpack will externalize
// modules using Node's module API (CommonJS 2)
output: { ...output, libraryTarget: 'commonjs2' },
// externalize all require() calls to non-relative modules.
// Unless you do something funky, every time you import a module
// from node_modules, it should match the regex below
externals: /^[a-z0-9-]/,
// Optional: use this if you want to be able to require() the
// server bundles from Node.js later
target: 'node'
}

Resources