Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use Webpack to create bundle for a Rest API Express NodeJS Server

Hope you are all well :)

I was working on a REST API server with Nodejs and after completing an alpha version, I wanted to create a bundle for it with build tools, Although I succeeded at some point in bundling the app still could not make the Express Rest API scripts to be bundled. As I am not really experienced with the Webpack, I am pretty sure that I am doing something wrong and there has to be a way to do this. You can also see my my webpack.config.js, .babelrc and package.json below:

Webpack.config.js

var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
var module_dir = `${__dirname}/node_modules`;
const path = require('path');

module.exports = {
  entry: {
    app: [
      'babel-polyfill',
      './index.js',
    ],
  },
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'app.bundle.js',
  },
  module: {
    rules: [{
        test: /\.js?$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: {
           presets: ['env', 'stage-0']
        }
    }]
  },
  resolveLoader: {
    modules: [
          __dirname + '/node_modules'
        ]
  }
}

.Babelrc

{
    "presets": ["@babel/env"]
}

package.json

{
  "name": "",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "nodemon index.js",
    "build": "webpack --mode production --progress"
  },
  "keywords": [
    "log",
    "npm",
    "node",
    "rest",
    "api",
    "debug",
    "bug"
  ],
  "author": "Mehdi Roshan Fekr",
  "license": "ISC",
  "dependencies": {
    "@babel/core": "^7.3.4",
    "@babel/preset-env": "^7.3.4",
    "express": "^4.16.4",
    "joi": "^14.3.1",
    "nodemon": "^1.18.10"
  },
  "devDependencies": {
    "@babel/core": "^7.1.6",
    "@babel/preset-env": "^7.1.6",
    "@babel/preset-react": "^7.0.0",
    "babel-loader": "^8.0.4",
    "webpack": "^4.25.1",
    "webpack-cli": "^3.1.2"
  }
}

I also have read this article about using express with webpack but I couldn't implement it properly, which I think one the reason for, is it is for a ReactJS app: How can I use webpack with express?

----Updates-----

Error

ERROR in ./index.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Cannot find module 'babel-preset-env' from 'C:\Projects\# App Projects\Qcentic-Log'
- Did you mean "@babel/env"?
    at Function.module.exports [as sync] (C:\Projects\# App Projects\Qcentic-Log\node_modules\resolve\lib\sync.js:58:15)
    at resolveStandardizedName (C:\Projects\# App Projects\Qcentic-Log\node_modules\@babel\core\lib\config\files\plugins.js:101:31)
    at resolvePreset (C:\Projects\# App Projects\Qcentic-Log\node_modules\@babel\core\lib\config\files\plugins.js:58:10)
    at loadPreset (C:\Projects\# App Projects\Qcentic-Log\node_modules\@babel\core\lib\config\files\plugins.js:77:20)
    at createDescriptor (C:\Projects\# App Projects\Qcentic-Log\node_modules\@babel\core\lib\config\config-descriptors.js:154:9)
    at items.map (C:\Projects\# App Projects\Qcentic-Log\node_modules\@babel\core\lib\config\config-descriptors.js:109:50)

index.js

const express = require('express');
const app = express();
const CustomModule = require('./CustomModule');
app.use(express.json());
//My Endpoints...
app.listen(80, () => console.log('Listening on port 80'));
like image 652
Mehdi Amenein Avatar asked Mar 13 '19 08:03

Mehdi Amenein


People also ask

Do we need webpack for Node js?

ES modules ( import ) But you don't need to use webpack for them work in node. Just use esm which is very lightweight and has no build step.


1 Answers

Since you are passing babel config directly to the loader, you do not need the .babelrc file. Also, you are using babel v7, so below is the updated config (your config and package.json contain mixed packages of babel v6 and v7 and they don't work together):

module.exports = {
    target: "node",
    entry: './index.js',
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: 'app.bundle.js',
    },
    module: {
        rules: [{
            test: /\.js?$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
                presets: [
                    [
                        "@babel/preset-env",
                        {
                            targets: {
                                node: "8.10"
                            }
                        }
                    ]
                ]
            }
        }]
    },
    resolveLoader: {
        modules: [
            __dirname + '/node_modules'
        ]
    }
}
  1. Note that I removed @babel/polyfill, you don't need it for the server environment (I am sure because I am also bundling my server code with webpack and never needed it).

  2. Make sure to set the version of node to whatever your target version is.

  3. Also note that query is a very old way of passing options to webpack loaders, so I updated it to the new syntax, using options. And it is always best to pass full name of babel plugins, e.g.: @babel/preset-env instead of just env. The old way of resolving plugin names would generate a babel-preset-env based on env, but since babel v7 they restructured the project to "scoped packages", thus the @babel/ prefix, so best to specify full name.
like image 139
Pavel Denisjuk Avatar answered Oct 31 '22 17:10

Pavel Denisjuk