1

I am stuck to build the node js project using webpack and I am using pug engine for front end.

My Project Structure:

bin 
controller
  - csv.controller.js
public
  - stylesheets
  - javascript
  - images
routes
  - csv.route.js
  - index.route.js
views
  - layouts
   -- layout.pug
  -index.pug
app.js

Package.json File

{
  "name": "csv",
  "version": "0.0.0",
  "private": true,
  "scripts": {
          "build": "webpack --mode=production",
          "build:dev": "webpack --mode=development",
          "start":"nodemon ./app.js",
          "start:dev": "webpack-dev-server --mode=development"
             },
  "dependencies": {
          "body-parser": "^1.19.0",
          "compression": "^1.7.4",
          "cookie-parser": "~1.4.4",
          "csv-parser": "^2.3.1",
          "csv-writer": "^1.5.0",
          "debug": "~2.6.9",
          "express": "^4.17.1",
          "express-fileupload": "^1.1.6-alpha.5",
          "fast-csv": "^3.4.0",
          "http-errors": "~1.6.3",
          "morgan": "^1.9.1",
          "multer": "^1.4.2",
          "npm-check-updates": "^3.1.23",
          "request": "^2.88.0"
         },
        "devDependencies": {
              "@babel/core": "^7.6.2",
              "@babel/preset-env": "^7.6.2",
              "babel-loader": "^8.0.6",
              "clean-webpack-plugin": "^3.0.0",
              "css-loader": "^3.2.0",
              "extract-text-webpack-plugin": "^3.0.2",
              "file-loader": "^4.2.0",
              "html-webpack-plugin": "^3.2.0",
              "mini-css-extract-plugin": "^0.8.0",
              "pug": "^2.0.4",
              "pug-loader": "^2.4.0",
              "style-loader": "^1.0.0",
              "webpack": "^4.40.2",
              "webpack-cli": "^3.3.9",
              "webpack-dev-server": "^3.8.1",
              "webpack-merge": "^4.2.2"
    }
  }

Actually what I want, after build, A dist folder contain a build.js or whatever its name and all public folder assets in the same directory. I tried with some below codes to build the project.

Webpack.config.js

 const path = require("path");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const ExtractTextPlugin = require("extract-text-webpack-plugin");
    const config = {
      entry: {
      app: "./app.js"
             },
      target: "node",
      output: {
      path: path.resolve(__dirname, "dist"),
      filename: "[name].bundle.js"
             },
      devServer: {
      port: 3000
            },
      plugins: [
      new HtmlWebpackPlugin({
         template: "./views/index.pug"
          })
        ],
     module: {
       rules: [
               {
                test: /\.pug$/,
                use: ["pug-loader"]
               },
               {
                test: /\.css$/,
                use: ["style-loader", "css-loader"]
               },
               {
                test: /\.(png|svg|jpg|gif)$/,
                use: ["file-loader"]
                },
               {
                test: [/.js$/],
                exclude: /(node_modules)/,
                  use: {
                      loader: "babel-loader",
                      options: {
                      presets: ["@babel/preset-env"]
                      }
                  }
               },
               {
                   test: /\.css$/,
                   use: ExtractTextPlugin.extract({
                   fallback: "style-loader",
                   use: "css-loader"
                  })
                }
              ]
          }
      }; 
 module.exports = (env, argv) => {
     if (argv.mode === "development") {
      }
     if (argv.mode === "production") {
      }
     return config;
  };
Graham
  • 7,431
  • 18
  • 59
  • 84
Awadhesh Kumar
  • 380
  • 2
  • 4
  • 14

1 Answers1

0

I know this question is old, but just in case somebody is looking for an answer.

You need another Webpack config for app.js, which is express entry point. Call it webpack.server.js or webpack.server.config.js or whatever convenient. Make sure to include webpack-node-externals: https://www.npmjs.com/package/webpack-node-externals

It may look something like this:

//webpack.server.js

const path = require('path');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');

module.exports = {

  return ({
    entry: {
      app: ./src/server/app.js,
    },
    output: {
      path: path.join(__dirname, 'dist'),
      publicPath: '/',
      filename: '[name].js',
    },
    target: 'node',
    node: {
      __dirname: false,
      __filename: false,
    },
    externals: [nodeExternals()],
    module: {
      rules: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
          },
        },
      ],
    },
  });
};


Also use webpack-dev-middleware in your app.js. See the below link:

https://webpack.js.org/guides/development/

In package.json include a script that looks something like this:

"server:dev": "webpack --config webpack.config.js && webpack --mode development --config webpack.server.js && node ./dist/app.js",

In your webpack.config.js make the entry point the js file that imports your front-end assets.. That is your stylesheets and any other js codes.. Not sure what css framework you are using. But, I am using tailwindcss and I have a js entry point file that imports tailwindcss and my other js codes. So essentially you may need two webpack config files one for the front-end and one for the express server. Hope I am making sense.

Sarah
  • 9
  • 3